/*
 * @(#)SearchDmsDocumentAction.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.dms.web;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.ConstantScoreRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

import com.dcivision.dms.DmsErrorConstant;
import com.dcivision.dms.DmsOperationConstant;
import com.dcivision.dms.bean.DmsContent;
import com.dcivision.dms.bean.DmsDefaultProfileSetting;
import com.dcivision.dms.bean.DmsDocument;
import com.dcivision.dms.bean.DmsDocumentDetail;
import com.dcivision.dms.bean.DmsLocMaster;
import com.dcivision.dms.bean.DmsQueryRecord;
import com.dcivision.dms.bean.DmsRelationalWord;
import com.dcivision.dms.bean.DmsRoot;
import com.dcivision.dms.bean.DmsValidation;
import com.dcivision.dms.bean.DmsVersion;
import com.dcivision.dms.core.ContentStoreException;
import com.dcivision.dms.core.DmsContentManager;
import com.dcivision.dms.core.DocumentOperationManager;
import com.dcivision.dms.core.DocumentRetrievalManager;
import com.dcivision.dms.core.DocumentValidateManager;
import com.dcivision.dms.core.ExcelUnReadableException;
import com.dcivision.dms.core.ParseQueryRecordXML;
import com.dcivision.dms.core.RootRetrievalManager;
import com.dcivision.dms.dao.DmsDocumentDAObject;
import com.dcivision.dms.dao.DmsQueryRecordDAObject;
import com.dcivision.dms.dao.DmsRelationalWordDAObject;
import com.dcivision.dms.dao.DmsRootDAObject;
import com.dcivision.dms.dao.MtmDocumentRelationshipDAObject;
import com.dcivision.framework.ApplicationContainer;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.MessageResourcesFactory;
import com.dcivision.framework.PermissionManager;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.UserInfoFactory;
import com.dcivision.framework.Utility;
import com.dcivision.framework.bean.SysUserDefinedIndex;
import com.dcivision.framework.bean.SysUserDefinedIndexDetail;
import com.dcivision.framework.dao.SysUserDefinedIndexDAObject;
import com.dcivision.framework.dao.SysUserDefinedIndexDetailDAObject;
import com.dcivision.framework.image.ImageUtility;
import com.dcivision.framework.web.AbstractListAction;
import com.dcivision.framework.web.AbstractSearchForm;
import com.dcivision.framework.web.model.BasePageModel;
import com.dcivision.lucene.FieldNames;
import com.dcivision.lucene.IndexDocument;
import com.dcivision.lucene.IndexKeywordParser;
import com.dcivision.lucene.IndexManager;
import com.dcivision.lucene.Pager;
import com.dcivision.user.bean.UserRecord;
import com.dcivision.user.dao.UserRecordDAObject;
/**
 * <p>Class Name:       SearchDmsDocumentAction.java    </p>
 * <p>Description:      The advance search action class for SearchDmsDocument.jsp</p>
 * @author              Zoe Shum
 * @company             DCIVision Limited
 * @creation date       01/08/2003
 * @version             $Revision: 1.226.2.22 $
 */
/* ********************************Modify History***********************************************
 * Modify by  : Jicle.Wang 
 * Modify date: 2006/08/25
 * BugID      : 6143
 * Description: Delete the shortCut with the document, 
 *              when you delete document in advance search
 * *********************************************************************************************
 */
public class SearchDmsDocumentAction extends AbstractListAction {

  public static final String REVISION = "$Revision: 1.226.2.22 $";
  public static final String PREVIOUS_FORM_KEY="PreviousSearchForm";

  protected int FULL_TEXT_SEARCH_RESULT_LENGTH = 200;

  /**
   *  Constructor - Creates a new instance of ListDmsDocumentAction and define the default listName.
   */
  public SearchDmsDocumentAction() {
    super();
    this.setListName("dmsDocumentSearchList");
  }
 
  /**
   * getMajorDAOClassName
   *
   * @return  The class name of the major DAObject will be used in this action.
   */
  
  public String getMajorDAOClassName() {
    return ("com.dcivision.dms.dao.DmsDocumentDAObject");
  }

  /**
   * getFunctionCode
   *
   * @return  The corresponding system function code of action.
   */
  
  public String getFunctionCode() {
    return (SystemFunctionConstant.DMS_PUBLIC_FOLDER);
  } 
  
  public void copyProperties(Object dset,Object orig) throws ApplicationException{
    try {
      BeanUtils.copyProperties(dset, orig);
    } catch (Exception exp) {
      log.error(exp);
      throw new ApplicationException(exp);
    }
  }
  
  public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException {
    HttpSession session = request.getSession();
    ListDmsDocumentForm searchForm = (ListDmsDocumentForm) form;
    String opMode = searchForm.getOpMode();

	  if(!Utility.isEmpty(session.getAttribute(Globals.MESSAGE_KEY))){
		  this.addMessage(request, (String)session.getAttribute(Globals.MESSAGE_KEY));
		  session.removeAttribute(Globals.MESSAGE_KEY);
	  }
	  if(!Utility.isEmpty(session.getAttribute(Globals.ERROR_KEY))){
		  this.addError(request, (String)session.getAttribute(Globals.ERROR_KEY));
		  session.removeAttribute(Globals.ERROR_KEY);
	  } 
	  
    //Export search result
	  if(DmsOperationConstant.ATTR_EXPORT_OPERATION.equals(opMode)
	      ||DmsOperationConstant.RESULT_EXPORT_OPERATION.equals(opMode)
	      ||DmsOperationConstant.EXPORT_EXCEL.equals(opMode)){
	    searchForm=(ListDmsDocumentForm)session.getAttribute(PREVIOUS_FORM_KEY);
      if(Utility.isEmpty(searchForm)){throw new ApplicationException("Query Criteria is Null!");}
      try {
         if (DmsOperationConstant.ATTR_EXPORT_OPERATION.equals(opMode)) {//key word search Zip Export
           exportSearchResult(mapping, searchForm, request, response);
           searchForm.setSearchResultOpt(null);
         }else if(DmsOperationConstant.RESULT_EXPORT_OPERATION.equals(opMode)) { //get excel file for advance search
           exportExcelAdvance(mapping, searchForm, request, response);
           searchForm.setSearchResultOpt(null);
         }else if(DmsOperationConstant.EXPORT_EXCEL.equals(opMode)) { //get excel file for bulk search
           exportExcel(mapping, searchForm, request, response);
         }
         getListData(mapping, searchForm, request, response);
      }catch (ApplicationException appEx) {
         rollback(request);
         handleApplicationException(request, appEx);
      }
      return mapping.findForward(GlobalConstant.NAV_MODE_LIST);
	  }else if(DmsOperationConstant.SEARCH_EDIT_CRITERIA.equals(opMode)){
        try{
        ListDmsDocumentForm previousForm=(ListDmsDocumentForm)session.getAttribute(PREVIOUS_FORM_KEY);
        copyProperties(form, previousForm);
        searchForm.setAdvSearchOpt("");
        }catch (ApplicationException appEx) {
          handleApplicationException(request, appEx);
       }
        return mapping.findForward(GlobalConstant.NAV_MODE_LIST);
      }
    
    // TODO: This line of code should be added on the before of every return action.
    // Every page maybe have special populating logic.
    request.setAttribute(BasePageModel.PAGE_MODEL_KEY, new AdvanceSearchPageModel(mapping, searchForm, request, response));
    //store the search criteria through page navigation
    if(!Utility.isEmpty(session.getAttribute("listDmsDocument")) && GlobalConstant.OP_MODE_LIST_RETAIN.equals(opMode)){
      String curStarRowNo = searchForm.getCurStartRowNo();
      String curPageNO = searchForm.getCurPageNO();//when set display_no_access_document parameter value to false, getPageList method use curPageNo to get result.
      searchForm = (ListDmsDocumentForm)session.getAttribute("listDmsDocument");
      searchForm.setCurStartRowNo(curStarRowNo);
      searchForm.setCurPageNO(curPageNO);
    }
    session.setAttribute("listDmsDocument",searchForm);
    /*
    if (!Utility.isEmpty(searchForm.getAdvSearchOpt()) && !Utility.isEmpty(session.getAttribute("advSearchOptToken"))) {
      ((ListDmsDocumentForm)form).setAdvSearchOpt((String)session.getAttribute("advSearchOptToken"));
    }
    */

    if (!Utility.isEmpty(searchForm.getAdvSearchOpt())) {
      session.setAttribute("advSearchOptToken",searchForm.getAdvSearchOpt());
    }

    log.debug("opMode = " + opMode);
    log.debug("search result option .... = " + searchForm.getSearchResultOpt());

    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);

    // Set function code if necessary.
    if (!Utility.isEmpty(searchForm.getCurFunctionCode())) {
      this.setFunctionCode(searchForm.getCurFunctionCode());
    }
    // Set the function code for current action.
    ActionForward forward = this.retrieveFunctionCode(request, response, mapping);
    if (forward != null) {
      return forward;
    }

    // Retrieve the default document profile settings.
    docRetrievalManager.checkNSetDefaultProfileList(request);

    //for keeping the document detail search criteria
    List list = docRetrievalManager.retrievalDocumentDetailsList(request);
    searchForm.setDocumentDetails(list);
    if(!Utility.isEmpty(session.getAttribute("udfDocList")) && GlobalConstant.OP_MODE_LIST_RETAIN.equals(opMode)){
      list = (List)session.getAttribute("udfDocList");
      searchForm.setDocumentDetails(list);
    }
    session.setAttribute("udfDocList",list);

    //Set public root folder for search
    if (Utility.isEmpty(searchForm.getSearchFolder())) {
      //Set the cur folder for search
      String rootID = request.getParameter("rootID");
      if (!Utility.isEmpty(rootID)) {
        String[] tmpSearchFolder = new String[1];
        tmpSearchFolder[0] = rootID;
        searchForm.setSearchFolder(tmpSearchFolder);
      } else {
        String[] selectedID = request.getParameterValues("basicSelectedID");
        if (!Utility.isEmpty(selectedID)) {
          searchForm.setSearchFolder(selectedID);
        }
      }
      String rootDocumentID = request.getParameter("rootDocumentID");
      request.getSession().setAttribute("searchFolderIds", rootDocumentID);
      if( !Utility.isEmpty(rootDocumentID)) {       
        String[] ids = new String[] {rootDocumentID};
        searchForm.setSearchFolder(ids);
      }
    }
    session.setAttribute(PREVIOUS_FORM_KEY,searchForm);
    sessionContainer = null;
    conn = null;
    docRetrievalManager.release();
    if("QUERY.PAGE".equals(searchForm.getNavMode())){
      return mapping.findForward("QUERY.PAGE");
    }
    if (opMode != null && !"".equals(opMode)) {
      if (DmsOperationConstant.ATTR_NEST_FILTER_OPERATION.equals(opMode)) {
        log.debug("nested search selection");
        try {
          this.getListData(mapping, searchForm, request, response);
        } catch (ApplicationException appEx) {
          this.rollback(request);
          handleApplicationException(request, appEx);
        }
        return mapping.findForward(GlobalConstant.NAV_MODE_LIST);

      } else if (DmsOperationConstant.ATTR_COMBINE_TIFF_OPERATION.equals(opMode)) { //Export and combine tiff result
        log.debug("enter combine tiff search result");
        try {
          combineTiffSearchResult(mapping, searchForm, request, response);
        } catch (ApplicationException appEx) {
          this.rollback(request);
          handleApplicationException(request, appEx);
        }
        searchForm.setSearchResultOpt(null);
        this.getListData(mapping, searchForm, request, response);
        return mapping.findForward(GlobalConstant.NAV_MODE_LIST);

      }else if (GlobalConstant.NAV_MODE_REFRESH.equals(opMode)) { //Refresh and get the UDF Details
        log.debug("enter refresh for UDF ");
        try {
          refreshFormData(mapping, searchForm, request, response);
        } catch (ApplicationException appEx) {
          this.rollback(request);
          handleApplicationException(request, appEx);
        }
        return mapping.findForward(GlobalConstant.NAV_MODE_LIST);

      } else if (GlobalConstant.OP_MODE_LIST_RETAIN.equals(opMode)) {
        try {
          refreshFormData(mapping, searchForm, request, response);
          this.getListData(mapping, searchForm, request, response);

        } catch (ApplicationException appEx) {
          this.rollback(request);
          handleApplicationException(request, appEx);
        }
        return mapping.findForward(GlobalConstant.NAV_MODE_LIST);
      } else if("QUERY.OPTION".equals(opMode)){
        try{
          this.selectQueryRecord(mapping,form,request,response);
          this.getListData(mapping, searchForm, request, response);
        }catch(ApplicationException appEx){
          this.rollback(request);
          handleApplicationException(request,appEx);
        }
        return mapping.findForward(GlobalConstant.NAV_MODE_LIST);
      }
      //delete a document in the search result list,the search result can retain
      else if (GlobalConstant.OP_MODE_LIST_DELETE.equals(searchForm.getOpMode())) {
        try {
        	 /* Jicle.Wang 6143 2006/08/25 Start */
        	//this.deleteListData(mapping, searchForm, request, response);
            this.deleteListData2(mapping, searchForm, request, response);
            /* Jicle.Wang 6143 2006/08/25 End   */
            //addMessage(request, MESSAGE_RECORDS_DELETED, ""+searchForm.getBasicSelectedID().length);
            refreshFormData(mapping, searchForm, request, response);
            this.getListData(mapping, searchForm, request, response);
            
            //Return to the first page automatically when del all record in the second page  
            List resultList = (List)request.getAttribute(this.m_sListName);
            while ( (resultList.size()==0) && (TextUtility.parseInteger(searchForm.getCurStartRowNo())>TextUtility.parseInteger(searchForm.getPageOffset())) ) {
              int prvRowNo = TextUtility.parseInteger(searchForm.getCurStartRowNo())-TextUtility.parseInteger(searchForm.getPageOffset());
              searchForm.setCurStartRowNo(TextUtility.formatInteger(prvRowNo));
              this.getListData(mapping, searchForm, request, response);
            }
        } catch (ApplicationException e) {
            this.rollback(request);
            this.handleApplicationException(request, e);
            request.setAttribute(this.m_sListName, new ArrayList());
        } finally {
        	this.getListData(mapping, searchForm, request, response);
        }
        return mapping.findForward(GlobalConstant.NAV_MODE_LIST);

      }else {
        return super.execute(mapping, searchForm, request, response);
      }
    }
    return super.execute(mapping, searchForm, request, response);
  }

  
  public void getListData(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    ListDmsDocumentForm searchForm = (ListDmsDocumentForm) form;
    String opMode = searchForm.getOpMode();
    SessionContainer sessionContainer = this.getSessionContainer(request);

    //Add By Jim.Zhou		2006/08/15		Bug #6031
    if("QUERY.OPTION".equals(opMode)){
    	Connection conn = this.getConnection(request);
      RootRetrievalManager rootRetrevalManager = new RootRetrievalManager(sessionContainer, conn);
      List rootList = rootRetrevalManager.getAllAccessibleRootsList();
      String[] ssFolder = searchForm.getSearchFolder();
      ArrayList tmpList = new ArrayList();
      int i = 0;
      int j = 0;
      for(; i<ssFolder.length; i++){
      	for(; j<rootList.size(); j++){
      		DmsRoot dmsRoot = (DmsRoot)rootList.get(j); 
      		if(ssFolder[i].equals(dmsRoot.getID().toString())){
      			tmpList.add(ssFolder[i]);
      			break;
      		}
      	}
      }
      if(tmpList.size()>0){
        String[] tmpStr = new String[tmpList.size()];
        for(i = 0; i<tmpList.size(); i++){
        	tmpStr[i] = tmpList.get(i).toString();
        }
        searchForm.setSearchFolder(tmpStr);
      }else{
      	searchForm.setSearchFolder(new String[0]);
      }
    }
    //Add End
    
    
    List resultList = new ArrayList();

    if (opMode != null && !"".equals(opMode) && !SystemParameterFactory.getSystemParameterBoolean(SystemParameterConstant.DMS_DISPLALY_NO_ACCESS_DOCUUMENT)){
    	resultList = this.getAccessListData(searchForm,mapping,request,response);
  	} else {
  		if (opMode != null && !"".equals(opMode)) {
        String opSearch = searchForm.getAdvSearchOpt();
        log.debug("opSearch = " + opSearch);

        if (DmsOperationConstant.ATTR_SEARCH_OPERATION.equals(opSearch)) {
          resultList = searchDocument(mapping, searchForm, request, response);
        } else if (DmsOperationConstant.KEYWORD_SEARCH_OPERATION.equals(opSearch)) {
          resultList = searchKeywordDocument(mapping, searchForm, request, response);
        } else if (DmsOperationConstant.ATTR_REPLACE_OPERATION.equals(opSearch)) {
          resultList = replaceCriteria(mapping, searchForm, request, response);
        } else if (DmsOperationConstant.ATTR_BULK_SEARCH_OPERATION.equals(opSearch)) {
          resultList = bulkSearchDocument(mapping, searchForm, request, response);
        }
      }else{
        searchForm.setIgnoreDuplicateShortcut("OR");      
      }
  	}
    
    if (DmsOperationConstant.ATTR_NEST_FILTER_OPERATION.equals(opMode)) {
      request.getSession().setAttribute(this.m_sListName, resultList);
      request.setAttribute(this.m_sListName, resultList);
    } else {
      request.setAttribute(this.m_sListName, resultList);
      request.getSession().setAttribute(this.m_sListName, new ArrayList());
    }

    this.retreiveWF(request);
  }

  public List getExportResultListData(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    ListDmsDocumentForm searchForm = (ListDmsDocumentForm) form;
    String opMode = searchForm.getOpMode();
    List resultList = new ArrayList();
    List resultListWithPermission = new ArrayList();
    //export will get the all of result record.
    searchForm.setSearchResultOpt(DmsOperationConstant.SEARCH_RESULT_ALL);   
    if (opMode != null) {
      String opSearch = searchForm.getAdvSearchOpt();
      if (DmsOperationConstant.ATTR_SEARCH_OPERATION.equals(opSearch)) {
        resultList = searchDocument(mapping, searchForm, request, response);
      } else if (DmsOperationConstant.KEYWORD_SEARCH_OPERATION.equals(opSearch)) { //Keyword Search
        resultList = searchKeywordDocument(mapping, searchForm, request, response);
      } else if (DmsOperationConstant.ATTR_BULK_SEARCH_OPERATION.equals(opSearch)) { //Bulk Search
        resultList = bulkSearchDocument(mapping, searchForm, request, response);
      }
    }

    if (!SystemParameterFactory.getSystemParameterBoolean(SystemParameterConstant.DMS_DISPLALY_NO_ACCESS_DOCUUMENT)){
    	List docList = new ArrayList();
    	Connection conn = this.getConnection(request);
    	SessionContainer sessionContainer = this.getSessionContainer(request);
    	PermissionManager pm = sessionContainer.getPermissionManager();
    	
    	DocumentRetrievalManager docRetrieval = new DocumentRetrievalManager(sessionContainer,conn);
    	DmsRootDAObject dmsRootDAO = new DmsRootDAObject(sessionContainer,conn);

      if (resultList != null){
       	for (int i=0;resultList.size()>i;i++){
      		DmsDocument dmsDoc = (DmsDocument)resultList.get(i);
      		
      		if (DmsDocument.DOCUMENT_LINK.equals(dmsDoc.getDocumentType())){    			
      			DmsDocument tmpDoc = docRetrieval.getRelationshipTargetDocument(dmsDoc.getID(),DmsDocument.DOCUMENT_LINK);
      			if (tmpDoc == null) {
                   continue;
                }
      			DmsRoot dmsRoot = (DmsRoot)dmsRootDAO.getObjectByID(tmpDoc.getRootID());  
      			
        		if (pm.hasAccessRight(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT,tmpDoc.getID(),"R") || dmsRoot.getOwnerID().equals(this.getSessionContainer(request).getUserRecordID())){
        			docList.add(dmsDoc);
        		} 
      		} else {
      			DmsRoot dmsRoot = (DmsRoot)dmsRootDAO.getObjectByID(dmsDoc.getRootID());
        		if (pm.hasAccessRight(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT,dmsDoc.getID(),"R") || dmsRoot.getOwnerID().equals(this.getSessionContainer(request).getUserRecordID())){
        			docList.add(dmsDoc);
        		}
      		} 		      
      	}
      }
      resultList = docList;
    }

    //filer the document that has permission
   /* SessionContainer sessionContainer = this.getSessionContainer(request);
    PermissionManager permissionManager = sessionContainer.getPermissionManager();

    for(int i=0;i<resultList.size();i++){
      DmsDocument tmpDmsDocument = (DmsDocument)resultList.get(i);
      String permission = (String)permissionManager.getPermission(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT, tmpDmsDocument.getID());
      if(permission.indexOf("R")>=0){
        resultListWithPermission.add(tmpDmsDocument);
      }
    }


    return resultListWithPermission;*/
    return resultList;
  }

  public List searchDocument(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);

    ListDmsDocumentForm searchForm = (ListDmsDocumentForm) form;

    List docList = new ArrayList();
    
    try {
      String rootID = searchForm.getRootID();
      String parentID = searchForm.getParentID();
      String[] searchFolder = searchForm.getSearchFolder();
      List targetRootIDs = Utility.getList(searchFolder);
      String[] outerCriteriaValue = (String[]) request.getSession().
        getAttribute("outerCriteriaValue");
      searchForm.setOuterCriteriaValue(outerCriteriaValue);

      //check for result list exported
      docList = (List) request.getAttribute(this.m_sListName);
      if (Utility.isEmpty(docList)) {
        docList = docRetrievalManager.searchDocumentBySearchObject(searchForm, targetRootIDs);
      }

      if (docList != null && docList.size() > 0) {
        DmsDocument tmpDoc = (DmsDocument) docList.get(0);
        String outerCriteria = tmpDoc.getOuterCriteria();
        searchForm.setOuterCriteria(outerCriteria);
        outerCriteriaValue = tmpDoc.getOuterCriteriaValue();
        request.getSession().setAttribute("outerCriteriaValue", outerCriteriaValue);
        searchForm.setOuterCriteriaValue(outerCriteriaValue);
      }
      
      if (DmsOperationConstant.SEARCH_RESULT_ALL.equals(searchForm.getSearchResultOpt())) {
        if (docList!=null) {
          // if equals SEARCH_RESULT_ALL, this method must be called by 'zip export' method. so we must filter unuseful records first.
          for (int i=(docList.size()-1); i>=0; i--) {
            DmsDocument dmsDocument = (DmsDocument)docList.get(i);
            if (!GlobalConstant.RECORD_STATUS_ACTIVE.equals(dmsDocument.getRecordStatus()) || DmsVersion.ARCHIVED_STATUS.equals(dmsDocument.getItemStatus())) {
              docList.remove(i);
            }else if (!DmsDocument.DOCUMENT_TYPE.equals(dmsDocument.getDocumentType()) && !DmsDocument.EMAIL_DOC_TYPE.equals(dmsDocument.getDocumentType()) && !DmsDocument.COMPOUND_DOC_TYPE.equals(dmsDocument.getDocumentType())) {
              docList.remove(i);
            }
          }
        }
      }
 
      //Use for List the target User Defined Fields Detail
      if (searchForm.getUserDefinedFieldID() != null) {
        List udfDetailList = docRetrievalManager.getUDFDetailList(TextUtility.parseIntegerObj(searchForm.getUserDefinedFieldID()));
        searchForm.setUdfDetailList(udfDetailList);
      }

      List docDetailList = searchForm.getDocumentDetails();
      if (docDetailList != null) {
        searchForm.setDocumentDetails(docDetailList);
      }
      sessionContainer = null;
      docRetrievalManager.release();
    } catch (ApplicationException appEx) {
      throw new ApplicationException(ErrorConstant.SYS_CHARACTER_ERROR, null, " \" ");
    } catch (Exception e) {
      log.error("Search error.", e);
      throw new ApplicationException(com.dcivision.dms.DmsErrorConstant.SEARCH_CRITERIA_NON_EXIST, e);
    } finally {
      conn = null;
    }
    return docList;
  }
  
  /**
   * high light search text for advance search. (lee 2006/11/12 EIP-69[update lucene])
   * @param text
   * @param highLightText
   * @param exactMatch
   * @return
   * @throws IOException
   */
  private String highLightAdvanceSearchText(String text, String highLightText, boolean exactMatch) throws IOException {
    if (Utility.isEmpty(text)) {
      return "-";
    }
    if (Utility.isEmpty(highLightText)) {
      return text;
    }
    if (exactMatch) {
      if (text.trim().toLowerCase().equals(highLightText.trim().toLowerCase())) {
        return "<B style='color:#0000ff'>"+text+"</B>";
      }else {
        return text;
      }
    }else {
      StringBuffer result = new StringBuffer(TextUtility.htmlEncode(text));
      String tmpSummary = result.toString().toLowerCase();
      String keyword = highLightText.toLowerCase();
      int keywordLengh = keyword.length();
      while (true) {
        int startIndex = tmpSummary.lastIndexOf(keyword);
        if (startIndex!=-1) {
          result.insert(startIndex+keywordLengh, "</B>");
          result.insert(startIndex, "<B style='color:#0000ff'>");
          tmpSummary = tmpSummary.substring(0, startIndex);
        }else {
          break;
        }
      }
      return result.toString();
    }
  }

  public List searchKeywordDocument(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    ListDmsDocumentForm searchForm = (ListDmsDocumentForm) form;
    
    List docList = new ArrayList();
    IndexManager indexManager = null;
    try {
      indexManager = new IndexManager(sessionContainer, conn);
      
      BooleanQuery booleanQuery = new BooleanQuery();
      Query query1 = null;
      Query query2 = null;
      Query query3 = null;
      Query query4 = null;
      Query query5 = null;
      Query query6 = null;
      Query query7 = null;

      Analyzer stdAnalyzer = indexManager.getAnalyzer(); 

      String keyword = searchForm.getKeyword().trim();
      IndexKeywordParser keywordParser = new IndexKeywordParser(sessionContainer, conn);
      keywordParser.parse(keyword);
      String convertKeyword = keywordParser.getParseKeywordString().trim();
      
      // set search fields
      String defaultIndexSize =SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_DEFAULT_PROFILE_FIELD_COUNT);
      int intDefaultIndexSize = (defaultIndexSize==null ? 0 : Integer.parseInt(defaultIndexSize));
      String userDefinedIndexSize =SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_MAX_INDEX_FIELDS);
      int intUserDefinedIndexSize = (userDefinedIndexSize==null ? 0 : Integer.parseInt(userDefinedIndexSize));
      String[] fields = new String[4+intDefaultIndexSize+intUserDefinedIndexSize];
      fields[0] = FieldNames.DOCUMENT_NAME; fields[1] = FieldNames.REFERENCE_NO;
      fields[2] = FieldNames.DESCRIPTION; fields[3] = FieldNames.CONTENT;
      for (int i=0; i<intDefaultIndexSize; i++) {
        fields[4+i] = FieldNames.DEFAULT_INDEXES+i;
      }
      for (int i=0; i<intUserDefinedIndexSize; i++) {
        fields[4+intDefaultIndexSize+i] = FieldNames.USER_DEFINED_INDEXES+i;
      }
      
      // set occur
      BooleanClause.Occur[] flags = new BooleanClause.Occur[4+intDefaultIndexSize+intUserDefinedIndexSize];
      for (int i=0; i<flags.length; i++) {
        flags[i] = BooleanClause.Occur.SHOULD;
      }

      query1 = MultiFieldQueryParser.parse(convertKeyword, fields, flags, stdAnalyzer);
      booleanQuery.add(query1, BooleanClause.Occur.MUST);
      
      // root limit
      String[] searchFolder = searchForm.getSearchFolder();
      
      // Search request from search page must verity whether the searchFolder is empty in client,
      // but if this request is come from global search, default selectFolder is all of accessible root folder.
      if (Utility.isEmpty(searchFolder)) {
        List accessibleFolders = (new RootRetrievalManager(sessionContainer, conn)).getAllAccessibleRootsList();
        searchFolder = new String[accessibleFolders.size()];
        for (int i = 0; i < accessibleFolders.size(); i++) {
          searchFolder[i] = ((DmsRoot) accessibleFolders.get(i)).getID().toString();
        }
      }
      
      String rootStr = "";
      if (!Utility.isEmpty(searchFolder)) {
        for (int i = 0; i < searchFolder.length; i++) {
          rootStr += (i==0 ? "" : " ")+"\"" + searchFolder[i] + "\"";
        }
      }
      rootStr += ")";
      query2 = new QueryParser(FieldNames.ROOT_ID, stdAnalyzer).parse(rootStr);
      booleanQuery.add(query2, BooleanClause.Occur.MUST);
      
      //user define field limit
      String[] searchUDF = searchForm.getSearchUDF();
      if (!Utility.isEmpty(searchUDF)) {
        String udfStr = "";
        for (int i = 0; i < searchUDF.length; i++) {
          udfStr += (i==0 ? "" : " ");
          udfStr += ("-1".equals(searchUDF[i]) ? "[\\-1 TO 0]" : searchUDF[i]);
        }
        query3 =  new QueryParser(FieldNames.USER_DEFINED_INDEX_ID, stdAnalyzer).parse(udfStr);
        booleanQuery.add(query3, BooleanClause.Occur.MUST);
      }
      
      query4 = new TermQuery(new Term(FieldNames.RECORD_STATUS, GlobalConstant.RECORD_STATUS_ACTIVE));
      booleanQuery.add(query4, BooleanClause.Occur.MUST);
      
      // Filter ORIGINSLITY_EMAIL_TYPE and TIF_ANNOTATION_TYPE document from search result. EIP-1296 07/01/18 LEE
      query5 = new TermQuery(new Term(FieldNames.DOCUMENT_TYPE, DmsDocument.ORIGINSLITY_EMAIL_TYPE));
      booleanQuery.add(query5, BooleanClause.Occur.MUST_NOT);
      query6 = new TermQuery(new Term(FieldNames.DOCUMENT_TYPE, DmsDocument.TIF_ANNOTATION_TYPE));
      booleanQuery.add(query6, BooleanClause.Occur.MUST_NOT);
      
      //Add a query. EIP-1129  Jim Zhou   2007/05/22
      Timestamp currTime = Utility.getCurrentTimestamp();
      query7 = new ConstantScoreRangeQuery(FieldNames.EFFECTIVE_START_DATE,currTime.toString(),null,true,true);
      booleanQuery.add(query7, BooleanClause.Occur.MUST_NOT);
      
      // if show expire is require need ......
      // if(!SystemParameterFactory.getSystemParameterBoolean(SystemParameterConstant.DMS_SHOW_EXPIRE_DOC)){

      // set sort object
      Sort sort = new Sort();
      boolean reverse = false;
      String sortAttribute = searchForm.getSortAttribute();
      String sortOrder = searchForm.getSortOrder();
      if((!Utility.isEmpty(sortAttribute)) && ("DESC".equals(sortOrder))) {
        reverse=true;
      }
      if(Utility.isEmpty(sortAttribute) ||Utility.isEmpty(sortOrder) || searchForm.getSortByScore()) {
        searchForm.setSortAttribute("");
        searchForm.setSortOrder("");
        sort.setSort(SortField.FIELD_SCORE);
      } else if("DOCUMENT_NAME".equals(sortAttribute)) {
        sort.setSort(FieldNames.DOCUMENT_NAME_SORT, reverse);
      } else if("ITEM_SIZE".equals(sortAttribute)) {
        sort.setSort(FieldNames.ITEM_SIZE, reverse);
      } else if("ITEM_STATUS".equals(sortAttribute)) {
        sort.setSort(FieldNames.ITEM_STATUS,reverse);
      } else if("UPDATER_ID".equals(sortAttribute)) {
        sort.setSort(FieldNames.UPDATER_ID, reverse);
      } else if("UPDATE_DATE".equals(sortAttribute)) {
        sort.setSort(FieldNames.UPDATE_DATE, reverse);
      } else {
        sort.setSort(SortField.FIELD_SCORE);
      }
      
      // set page information

      int pageSize = TextUtility.parseInteger(searchForm.getPageOffset());
      int startOffset = TextUtility.parseInteger(searchForm.getCurStartRowNo());
      Pager pager = new Pager();
      if (DmsOperationConstant.SEARCH_RESULT_ALL.equals(searchForm.getSearchResultOpt())) {
        pager.setPageSize(999999999);
        pager.setPageIndex(1);
      }else {
        pager.setRecordStartOffset(startOffset-1);
        pager.setPageSize(pageSize);
      }
      

      // begin search lucenes
      List indexDocumentList = indexManager.queryIndexDocuments(booleanQuery, sort, pager);
      
      DmsDocumentDAObject dmsDocumentDAO = new DmsDocumentDAObject(sessionContainer, conn);
      
      int counter = 0; //some dms document is not exist in database, can't use i to record index.
      for (int i=0; i<indexDocumentList.size(); i++) {
        IndexDocument indexDocument = (IndexDocument)indexDocumentList.get(i);
        DmsDocument dmsDocument= (DmsDocument)dmsDocumentDAO.getObjectByID(new Integer(indexDocument.getUid()));
        if (dmsDocument!=null) {
          if (DmsOperationConstant.SEARCH_RESULT_ALL.equals(searchForm.getSearchResultOpt())) {
            // if equals SEARCH_RESULT_ALL, this method must be called by 'zip export' method. so we must filter unuseful records first.
            if (GlobalConstant.RECORD_STATUS_ACTIVE.equals(dmsDocument.getRecordStatus()) && !DmsVersion.ARCHIVED_STATUS.equals(dmsDocument.getItemStatus())) {
              if ( DmsDocument.DOCUMENT_TYPE.equals(dmsDocument.getDocumentType()) || DmsDocument.EMAIL_DOC_TYPE.equals(dmsDocument.getDocumentType()) || DmsDocument.COMPOUND_DOC_TYPE.equals(dmsDocument.getDocumentType())) {
                docList.add(dmsDocument);
              }
            }
          }else {
            // set page information and highlight search result.
            dmsDocument.setRowNum(startOffset + counter);
            dmsDocument.setRecordCount(pager.getRecordCount());
            docList.add(dmsDocument);
            request.setAttribute("DCI_SCORE_" + counter, String.valueOf( (double) Math.round( 1000 * indexDocument.getScore() / 10.0)));
  
            String allRelatedIndexs = this.getRelatedHighLightText(indexManager, request, booleanQuery, keywordParser.getParseKeywordList(), indexDocument);
            request.setAttribute("DCI_ALL_RELATED_INDEXES_" + counter, allRelatedIndexs);
            
            String content = indexDocument.getContent();
            if (Utility.isEmpty(content)) {
              request.setAttribute("DCI_FULLTEXT_" + counter, null);
            }else {
              String highText = indexManager.getHtmlHighLight(booleanQuery, keywordParser.getParseKeywordList(), indexDocument.getId(), indexDocument.getContent(), FieldNames.CONTENT);
              if (Utility.isEmpty(highText)) {
                if (content!=null && content.length()>200) {
                  highText = content.substring(0,200);
                }else {
                  highText = content;
                }
              }
              request.setAttribute("DCI_FULLTEXT_" + counter, highText);
            }
          }
          counter ++;
        }
      }
      searchForm.setSortByScore(false);
      sessionContainer = null;
    }catch(ApplicationException apEx){
      throw apEx;
    } catch (Exception e) {
      log.error("Search error.", e);
    } finally {
      indexManager.close();
      conn = null;
    }
    return docList;
  }
  
  private String getRelatedHighLightText(
      IndexManager indexManager, 
      HttpServletRequest request, 
      Query query,
      List keywords, 
      IndexDocument indexDocument) throws Exception {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    
    StringBuffer sb = new StringBuffer();
    
    sb.append("<B>DOCUMENT NAME:</B>");
    if (!Utility.isEmpty(indexDocument.getDocumentName())) {
      String highText = indexManager.getHtmlHighLight(query, keywords, indexDocument.getId(), indexDocument.getDocumentName(), FieldNames.DOCUMENT_NAME);
      sb.append(Utility.isEmpty(highText) ? indexDocument.getDocumentName() : highText);
    }else {
      sb.append("-");
    }
    sb.append("&nbsp;&nbsp;&nbsp;");
    
    sb.append("<B>REFERENCE NO:</B>");
    if (!Utility.isEmpty(indexDocument.getReferenceNo())) {
      String highText = indexManager.getHtmlHighLight(query, keywords, indexDocument.getId(), indexDocument.getReferenceNo(), FieldNames.REFERENCE_NO);
      sb.append(Utility.isEmpty(highText) ? indexDocument.getReferenceNo() : highText);
    }else {
      sb.append("-");
    }
    sb.append("&nbsp;&nbsp;&nbsp;");
    
    sb.append("<B>DESCRIPTION:</B>");
    if (!Utility.isEmpty(indexDocument.getDescription())) {
      String highText = indexManager.getHtmlHighLight(query, keywords, indexDocument.getId(), indexDocument.getDescription(), FieldNames.DESCRIPTION);
      sb.append(Utility.isEmpty(highText) ? indexDocument.getDescription() : highText);
    }else {
      sb.append("-");
    }
    sb.append("&nbsp;&nbsp;&nbsp;");
    
    List lstDefaultIndexes = (List)request.getSession().getServletContext().getAttribute(DmsOperationConstant.DMS_DEFAULT_PROFILE_SETTING);
    if (lstDefaultIndexes!=null) {
      String defaultIndexSize =SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_DEFAULT_PROFILE_FIELD_COUNT);
      int intDefaultIndexSize = (defaultIndexSize==null ? 10 : Integer.parseInt(defaultIndexSize));
      Map defaultIndexes = indexDocument.getDefaultIndexes();
      for (int idx=0; idx<intDefaultIndexSize; idx++) {
        DmsDefaultProfileSetting setting = ((DmsDefaultProfileSetting)lstDefaultIndexes.get(idx));
        String indexText = (defaultIndexes!=null ? (String)defaultIndexes.get(new Integer(idx)) : null);
        sb.append("<B>"+setting.getFieldName()+":</B>");
        if (!Utility.isEmpty(indexText)) {
          String highText = indexManager.getHtmlHighLight(query, keywords, indexDocument.getId(), indexText, FieldNames.DEFAULT_INDEXES+idx);
          sb.append(Utility.isEmpty(highText) ? indexText : highText);
        }else {
          sb.append("-");
        }
        sb.append("&nbsp;&nbsp;&nbsp;");
      }
    }
    
    String userDefinedIndexDetailIds = indexDocument.getUserDefinedIndexDetailIds();
    Map userDefinedIndexes = indexDocument.getUserDefinedIndexes();
    if (userDefinedIndexDetailIds!=null && userDefinedIndexes!=null) {
      SysUserDefinedIndexDetailDAObject sysUseDefIndexDetailDAO = new SysUserDefinedIndexDetailDAObject(sessionContainer, conn);
      String[] arrIndexDetailId = userDefinedIndexDetailIds.split(" ");
      for (int m=0; m<arrIndexDetailId.length; m++) {
        String label = ((SysUserDefinedIndexDetail)sysUseDefIndexDetailDAO.getObjectByID(new Integer(arrIndexDetailId[m]))).getFieldName();
        String detailText = (String)userDefinedIndexes.get(new Integer(m));
        sb.append("<B>"+label+":</B>");
        if (label!=null && detailText!=null) {
          String highText = indexManager.getHtmlHighLight(query, keywords, indexDocument.getId(), detailText, FieldNames.USER_DEFINED_INDEXES+m);
          sb.append(Utility.isEmpty(highText) ? detailText : highText);
        }else {
          sb.append("-");
        }
        sb.append("&nbsp;&nbsp;&nbsp;");
      }
    }
    return sb.toString();
  }
  

  /**
   * combine tiff searching results
   *
   */
  public void combineTiffSearchResult(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    DocumentOperationManager docOperationManager = new DocumentOperationManager(sessionContainer, conn);
    RootRetrievalManager rootRetrievalManager = new RootRetrievalManager(sessionContainer, conn);
    DmsContentManager dmsContentManager = new DmsContentManager(sessionContainer, conn);
    
    
    ListDmsDocumentForm searchForm = (ListDmsDocumentForm) form;

    List defaultProfileSettingList = new ArrayList();
    int totalFieldCount = 0;

    try {
      searchForm.setSearchResultOpt(DmsOperationConstant.SEARCH_RESULT_ALL);
      List docList = this.getExportResultListData(mapping, searchForm, request, response);
      List allDocList = new ArrayList();
      allDocList.addAll(docList);
      for (int i = 0; i < allDocList.size(); i++) {
        Integer docID = ( (DmsDocument) docList.get(i)).getID();
        if (DmsDocument.COMPOUND_DOC_TYPE.equals( ( (DmsDocument) docList.get(i)).getDocumentType())) {
          if (checkIsTiff(docID, request, response)) {
            List subList = docOperationManager.getSubDocumentByParentID( ( (DmsDocument) docList.get(i)).getID());
            allDocList.addAll(subList);
          }
        }
      }
      log.debug("completed search result list= " + docList.size());

      /* creating excel file */
      HSSFWorkbook wb = new HSSFWorkbook();
      HSSFSheet sheet = wb.createSheet("result");
      sheet.setDefaultColumnWidth( (short) 18);
      short rowNum = 0;
      HSSFRow row = sheet.createRow(rowNum++);

      // search criteria
      createCell(wb, row, (short) 0, "Search Criteria");
      row = sheet.createRow(rowNum++);
      createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_D"));
      createCell(wb, row, (short) 1, searchForm.getDocumentName());
      row = sheet.createRow(rowNum++);
      /*createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.owner"));
           createCell(wb, row, (short) 1, searchForm.getEffectiveStartDate());
             row = sheet.createRow(rowNum++);*/
      createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.description"));
      createCell(wb, row, (short) 1, searchForm.getDescription());
      row = sheet.createRow(rowNum++);
      createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.reference_no"));
      createCell(wb, row, (short) 1, searchForm.getReferenceNo());

      /* common profile */

      /* end of common profile */
      //Use for List the target User Defined Fields Detail
      List udfDetailList = new ArrayList();
      if (searchForm.getUserDefinedFieldID() != null) {
        udfDetailList = docRetrievalManager.getUDFDetailList(TextUtility.parseIntegerObj(searchForm.getUserDefinedFieldID()));
        searchForm.setUdfDetailList(udfDetailList);
      }

      List docDetailList = searchForm.getDocumentDetails();
      //DmsDocumentDetail docDetail = null;
      DmsDocumentDetail docDetail = new DmsDocumentDetail();

      //similar to exportSearch result
      if (!Utility.isEmpty(docDetailList)) {
        docDetail = (DmsDocumentDetail) docDetailList.get(0);
      }

      row = sheet.createRow(rowNum++);
      createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.user_defined_index"));
      SysUserDefinedIndex udfIndex = docRetrievalManager.getUDF(docDetail.getUserDefinedFieldID());
      if (udfIndex != null) {
        createCell(wb, row, (short) 1, udfIndex.getUserDefinedType());
      }

      //similar to exportSearch result
      //DmsDocumentDetail docDetail = null;
      //SysUserDefinedIndexDetail udfDetail = null;
      SysUserDefinedIndexDetail udfDetail = new SysUserDefinedIndexDetail();
      //Loop the UDF and input the result
      if (!Utility.isEmpty(udfDetailList)) {
        for (int k = 0; k < udfDetailList.size(); k++) {
          udfDetail = (SysUserDefinedIndexDetail) udfDetailList.get(k);
          row = sheet.createRow(rowNum++);
          createCell(wb, row, (short) 0, udfDetail.getFieldName());
          if (SysUserDefinedIndexDetail.DATE_FIELD.equals(udfDetail.getFieldType())) {
            createCell(wb, row, (short) 1, TextUtility.formatTimestampToDate(docDetail.getDateValue()));
            createCell(wb, row, (short) 2, TextUtility.formatTimestampToDate(docDetail.getToDateValue()));
          } else if (SysUserDefinedIndexDetail.NUMBER_FIELD.equals(udfDetail.getFieldType())) {
            createCell(wb, row, (short) 1, TextUtility.formatDoubleObj(docDetail.getNumericValue()));
            createCell(wb, row, (short) 2, TextUtility.formatDoubleObj(docDetail.getToNumericValue()));
          } else {
            createCell(wb, row, (short) 1, docDetail.getFieldValue());
            createCell(wb, row, (short) 2, docDetail.getToFieldValue());
          }
        }
      } //End of docDetail retrieval

      row = sheet.createRow(rowNum++); //empty row

      //search result
      row = sheet.createRow(rowNum++);
      createCell(wb, row, (short) 0, "Search Result");

      row = sheet.createRow(rowNum++);
      createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_D"));
      createCell(wb, row, (short) 1, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.location"));
      createCell(wb, row, (short) 2, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.document_type"));
      createCell(wb, row, (short) 3, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.columnheader.item_size"));
      createCell(wb, row, (short) 4, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "common.label.creator_name"));
      createCell(wb, row, (short) 5, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.columnheader.profile_name"));      
      createCell(wb, row, (short) 6, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.reference_no"));
      createCell(wb, row, (short) 7, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.description"));
      createCell(wb, row, (short) 8, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.columnheader.item_status"));

      int nUdfRow = 9;
      if (!Utility.isEmpty(udfDetailList)) {
        for (int l = udfDetailList.size() - 1; l >= 0; l--) {
          udfDetail = (SysUserDefinedIndexDetail) udfDetailList.get(l);
          if (SysUserDefinedIndexDetail.DATE_FIELD.equals(udfDetail.getFieldType())) {
            createCell(wb, row, (short) (nUdfRow + l), udfDetail.getFieldName());
          } else {
            createCell(wb, row, (short) (nUdfRow + l), udfDetail.getFieldName());
          }
        }
      } //End of docDetail retrieval

      PermissionManager permissionManager = sessionContainer.getPermissionManager();
      int noOfFileWithPermission =0;
      DmsDocument document = new DmsDocument();
      for (int i = 0; i < docList.size(); i++) {
        document = (DmsDocument) docList.get(i);

        String permission = permissionManager.getPermission(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT, document.getID());
        if(permission.indexOf("R")>=0){
          noOfFileWithPermission++;

        /*handle if the document is short cut, get the real document*/
        if (DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType())) {
          MtmDocumentRelationshipDAObject docRelationshipDAO = new MtmDocumentRelationshipDAObject(sessionContainer, conn);
          Integer targetDocID = docRelationshipDAO.getTargetDocIDByRelatedDocID(document.getID(), document.getDocumentType());
          DmsDocument targetDoc = docRetrievalManager.getDocument(targetDocID);
          /* Used to update the doc link name and type; Wont infulence the getDocumentProfileInfo() */
          targetDoc.setDocumentName(document.getDocumentName());
          targetDoc.setDocumentType(document.getDocumentType());
          document = targetDoc;
        }

        /*End of handle if the document is short cut, get the real document*/
        //get the document type display name

        String displayDocType = "";
        if (DmsDocument.DOCUMENT_TYPE.equals(document.getDocumentType())) {
          displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_D");
        } else if (DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType())) {
          displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_L");
        } else if (DmsDocument.COMPOUND_DOC_TYPE.equals(document.getDocumentType())) {
          displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_C");
        }

        if (document.getDocumentName().toUpperCase().indexOf("TIF") > 0) {
          row = sheet.createRow(rowNum++);
          createCell(wb, row, (short) 0, document.getDocumentName());
          createCell(wb, row, (short) 1, docRetrievalManager.getLocationPath(document.getParentID()));
          createCell(wb, row, (short) 2, displayDocType);
          createCell(wb, row, (short) 3, TextUtility.formatFileSize(document.getItemSize().intValue()));
          String userName = UserInfoFactory.getUserFullName(document.getCreatorID());            
          createCell(wb, row, (short) 4, userName);          
          String udfName = docRetrievalManager.getUserDefinedTypeByDocumentID(document.getID());
          createCell(wb, row, (short) 5, udfName);          
          createCell(wb, row, (short) 6, document.getReferenceNo());
          createCell(wb, row, (short) 7, document.getDescription());
          createCell(wb, row, (short) 8, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_lock_" + document.getItemStatus()));

          /* common profile */
          nUdfRow = 9;
          //Common Profile
          /* end of common profile */

          List resultUDFDetailList = new ArrayList();

          if (searchForm.getUserDefinedFieldID() != null) {
            searchForm.setUdfDetailList(udfDetailList);
          }
          List resultDocDetailList = docRetrievalManager.getDocumentDetailList(document.getID());

          if (!Utility.isEmpty(resultDocDetailList)) {
            //resultUDFDetailList = docRetrievalManager.getUDFDetailList(((DmsDocumentDetail)resultDocDetailList.get(0)).getUserDefinedFieldID());
            for (int k = 0; k < udfDetailList.size(); k++) {
              udfDetail = (SysUserDefinedIndexDetail) udfDetailList.get(k);
              for (int l = 0; l < resultDocDetailList.size(); l++) {
                docDetail = (DmsDocumentDetail) resultDocDetailList.get(l);
                if (udfDetail.getID().equals(docDetail.getUserDefinedFieldDetailID())) {
                  if (SysUserDefinedIndexDetail.DATE_FIELD.equals(udfDetail.getFieldType())) {
                    createCell(wb, row, (short) (nUdfRow + l), TextUtility.formatTimestampToDate(docDetail.getDateValue()));
                  } else if (SysUserDefinedIndexDetail.DATE_FIELD.equals(udfDetail.getFieldType())) {
                    createCell(wb, row, (short) (nUdfRow + l), TextUtility.formatDoubleObj(docDetail.getNumericValue()));
                  } else {
                    createCell(wb, row, (short) (nUdfRow + l), docDetail.getFieldValue());
                  }
                }
              }
            }
          }
        }
        }//end permission check
      } //End of Document result insert

      ByteArrayOutputStream byteOut = new ByteArrayOutputStream();

      wb.write(byteOut);
      byte[] excelData = byteOut.toByteArray();
      if (excelData == null) {
        log.debug("die!");
      } else {
        log.debug("not die");
      }

      byteOut.close();
      /* end of creating excel */

      //start of sending email, creating Zip
      String subject = "Search Result";
      String contentPart = "";
      String ID = "0";

      StringBuffer content = new StringBuffer("Attached please find the search criteria and search results ");
      //content.append(document.getDocumentName()).append("' is being created.\n\n");
      //content.append(contentPart);

      UserRecordDAObject userDAO = new UserRecordDAObject(sessionContainer, conn);
      UserRecord senderUser = (UserRecord) userDAO.getObjectByID(sessionContainer.getUserRecordID());

      //adding attachments to the emails
      String tempConvertedName = String.valueOf(System.currentTimeMillis());
      StringBuffer tempZipFile = new StringBuffer();
      DmsLocMaster locMaster = rootRetrievalManager.getLocMasterOfPersonalRootByOwnerID(sessionContainer.getUserRecordID());
      String locMasterPath = locMaster.getLocPath();
      log.debug("locMasterPath = " + locMasterPath);
      tempZipFile = tempZipFile.append(locMasterPath).append("/").append(tempConvertedName).append(".zip");
//      FileOutputStream f = new FileOutputStream(tempZipFile.toString());
//      CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());
//      ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(csum));
      ZipOutputStream out= new ZipOutputStream(new FileOutputStream(tempZipFile.toString()));       
      /*
       * Update Code Start
       * Author			Jim.Zhou
       * Date			2006/04/12
       * Bug			#4820
       */
      DocumentRetrievalManager docRetrieval = new DocumentRetrievalManager(sessionContainer,conn);
      out.setEncoding(docRetrieval.getZipFileDefaultEncode());
      /*
       * Update Code End
       */
 
      //String[] tifList = new String[docList.size()];

      String[] tifList = new String[noOfFileWithPermission];

      String foldersDir = "";
      int outputTifCounter =0;
      for (int i = 0; i < allDocList.size(); i++) {
        document = (DmsDocument) allDocList.get(i);

        String permission1 = permissionManager.getPermission(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT, document.getID());
        if(permission1.indexOf("R")>=0){
          outputTifCounter++;
        /*handle if the document is short cut, get the real document*/
        if (DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType())) {
          MtmDocumentRelationshipDAObject docRelationshipDAO = new MtmDocumentRelationshipDAObject(sessionContainer, conn);
          Integer targetDocID = docRelationshipDAO.getTargetDocIDByRelatedDocID(document.getID(), document.getDocumentType());
          DmsDocument targetDoc = docRetrievalManager.getDocument(targetDocID);
          /* Used to update the doc link name and type; Wont infulence the getDocumentProfileInfo() */
          targetDoc.setDocumentName(document.getDocumentName());
          targetDoc.setDocumentType(document.getDocumentType());
          document = targetDoc;
        }

        /*End of handle if the document is short cut, get the real document*/
        String name = document.getDocumentName();

        if ("TIF".equals(TextUtility.getExtension(name)) || "TIFF".equals(TextUtility.getExtension(name))) {
          DmsVersion topVersion = docRetrievalManager.getTopVersionByDocumentID(document.getID());
          DmsContent topContent = docRetrievalManager.getContentByContentID(topVersion.getContentID());
         
          String tifPhysicalLocation = dmsContentManager.getDmsDocumentStoreFilePysicalPath(document,topContent);          

          //tifList[i] = tifPhysicalLocation;
          tifList[outputTifCounter-1] = tifPhysicalLocation;

          log.debug("Tiff added name = " + name);
        }
        }//end of permission check
      }

      // Combine tif file.
      String filename = foldersDir + tempConvertedName + "_COMBINED_TIFF.tif";
      String contentType = "image/tiff";
      FileOutputStream tiffOutput = null;
      try {
        tiffOutput = new FileOutputStream(filename);
        ImageUtility tiffCom = new ImageUtility();

        if(tifList.length>0){

          tiffCom.combineTiff(tifList, tiffOutput);
        }
      } catch (Exception e) {
        log.error(e, e);
        addError(request, DmsErrorConstant.RESULT_ZIP_FAILED);
      } finally {
        try { tiffOutput.close(); } catch (Exception ignore) {} finally { tiffOutput = null; }
      }

      // for zip combined tif
      FileInputStream in = null;
      File combinedTif = null;
      try {
        if(tifList.length>0){
          log.debug("zip the tiff");
          combinedTif = new File(filename);
          in = new FileInputStream(combinedTif);
          out.putNextEntry(new ZipEntry("COMBINED_TIFF.tif"));
          int c;
          while ( (c = in.read()) != -1) {
            out.write(c);
          }
        }
      } catch (Exception e) {
        log.error(e, e);
        if (DmsVersion.ARCHIVED_STATUS.equals(document.getItemStatus())) {
          addError(request,DmsErrorConstant.RESULT_ZIP_ARCHIVED_FILE_FAILED);
        }else{
          addError(request, DmsErrorConstant.RESULT_ZIP_FAILED);
        }
      } finally {
        try { in.close(); } catch (Exception ignore) {} finally { in = null; }
      }

      //adding the excel file to the zip
      ByteArrayInputStream bis = null;
      try {
        bis = new ByteArrayInputStream(excelData);
        out.putNextEntry(new ZipEntry("SEARCH_RESULTS.xls"));
        int c;
        while ( (c = bis.read()) != -1) {
          out.write(c);
        }
      } catch (Exception e) {
        log.error(e, e);
        addError(request, DmsErrorConstant.RESULT_ZIP_FAILED);
      } finally {
        try { bis.close(); } catch (Exception ignore) {} finally { bis = null; }
        try { out.close(); } catch (Exception ignore) {} finally { out = null; }
        try { combinedTif.delete(); } catch (Exception ignore) {} finally { combinedTif = null; }
      }

      /*- by harry on 21/05/2003, use save as instead
             EmailDeliveryMessage msg = new EmailDeliveryMessage();
             msg.addAttachment("result_files.zip", zipByte);
             msg.addAttachment("SEARCH_RESULTS.xls", excelData);
             msg.setSubject(subject);
             msg.setMailContent(content.toString());
             msg.setSender(new GenericAddress(senderUser.getEmail() != null ? senderUser.getEmail() : "", senderUser.getLastName() + " " + senderUser.getFirstName()));
             msg.addToRecipient(new GenericAddress(senderUser.getEmail()));
             if (msg.getToRecipientList().size() > 0) {
        NotificationWay emailNotification = NotificationWayFactory.getNotificationInstance(NotificationWay.EMAIL_NOTIFICATION_INSTANCE);
        emailNotification.addDeliveryMessage((DeliveryMessage) msg);
        emailNotification.send();
             }
       */
      //end of sending email

      request.getSession().setAttribute("zipExportFileName", tempZipFile.toString());
      //request.setAttribute(this.m_sListName, docList);
      sessionContainer = null;
      docRetrievalManager.release();
      rootRetrievalManager.release();
    } catch (Exception e) {
      log.error("Search error.", e);
    } finally {
      conn = null;
    }
  }

  /**
   * export searching criteria and results to excel file[ and send to user via email]
   *
   */
  public void exportSearchResult(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    RootRetrievalManager rootRetrievalManager = new RootRetrievalManager(sessionContainer, conn);
    DmsContentManager dmsContentManager = new DmsContentManager(sessionContainer, conn);
    
    
    ListDmsDocumentForm searchForm = (ListDmsDocumentForm) form;
    List defaultProfileSettingList = new ArrayList();
    int totalFieldCount = 0;
    try {
      searchForm.setSearchResultOpt(DmsOperationConstant.SEARCH_RESULT_ALL);
      List docList = this.getExportResultListData(mapping, searchForm, request, response);
      log.debug("completed search result list= " + docList.size());

      /* creating excel file */
      HSSFWorkbook wb = new HSSFWorkbook();
      HSSFSheet sheet = wb.createSheet("result");
      sheet.setDefaultColumnWidth( (short) 18);
      short rowNum = 0;
      HSSFRow row = sheet.createRow(rowNum++);

      //Use for List the target User Defined Fields Detail
      List udfDetailList = new ArrayList();
      SysUserDefinedIndexDetail udfDetail = new SysUserDefinedIndexDetail();
      DmsDocumentDetail docDetail = new DmsDocumentDetail();
      if (searchForm.getUserDefinedFieldID() != null) {
        udfDetailList = docRetrievalManager.getUDFDetailList(TextUtility.parseIntegerObj(searchForm.getUserDefinedFieldID()));
        searchForm.setUdfDetailList(udfDetailList);
      }

      // search criteria for Advance Search
      if (DmsOperationConstant.ATTR_SEARCH_OPERATION.equals(searchForm.getAdvSearchOpt())) {
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.search_criteria"));
        row = sheet.createRow(rowNum++);
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_D"));
        createCell(wb, row, (short) 1, searchForm.getDocumentName());
        row = sheet.createRow(rowNum++);
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.effective_date"));
        createCell(wb, row, (short) 1, searchForm.getEffectiveStartDate());
        createCell(wb, row, (short) 2, searchForm.getEffectiveEndDate());
        row = sheet.createRow(rowNum++);
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.description"));
        createCell(wb, row, (short) 1, searchForm.getDescription());
        row = sheet.createRow(rowNum++);
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.reference_no"));
        createCell(wb, row, (short) 1, searchForm.getReferenceNo());

        //Common profiles
        defaultProfileSettingList = (List) request.getSession().getServletContext().getAttribute("DMS_DEF_PROFILE");
        totalFieldCount = Integer.parseInt(com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.DMS_DEFAULT_PROFILE_FIELD_COUNT));
        if (!Utility.isEmpty(defaultProfileSettingList)) {
          for (int i = 0; i < totalFieldCount; i++) {
            row = sheet.createRow(rowNum++);
            DmsDefaultProfileSetting setting = ( (DmsDefaultProfileSetting) defaultProfileSettingList.get(i));
            createCell(wb, row, (short) 0, setting.getFieldName());
            String userDefValue = "";
            switch (i) {
            case 0:
              userDefValue = searchForm.getUserDef1();
              break;
            case 1:
              userDefValue = searchForm.getUserDef2();
              break;
            case 2:
              userDefValue = searchForm.getUserDef3();
              break;
            case 3:
              userDefValue = searchForm.getUserDef4();
              break;
            case 4:
              userDefValue = searchForm.getUserDef5();
              break;
            case 5:
              userDefValue = searchForm.getUserDef6();
              break;
            case 6:
              userDefValue = searchForm.getUserDef7();
              break;
            case 7:
              userDefValue = searchForm.getUserDef8();
              break;
            case 8:
              userDefValue = searchForm.getUserDef9();
              break;
            case 9:
              userDefValue = searchForm.getUserDef10();
              break;
            }
            if (Utility.isEmpty(userDefValue)) {
              userDefValue = "";
            }
            createCell(wb, row, (short) 1, userDefValue);
          }
        }

        List docDetailList = searchForm.getDocumentDetails();
        if (!Utility.isEmpty(docDetailList)) {
          docDetail = (DmsDocumentDetail) docDetailList.get(0);
        }


        row = sheet.createRow(rowNum++);
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.user_defined_index"));
        SysUserDefinedIndex udfIndex = docRetrievalManager.getUDF(docDetail.getUserDefinedFieldID());
        if (udfIndex != null) {
          createCell(wb, row, (short) 1, udfIndex.getUserDefinedType());
        }

        //Loop the UDF and input search criteria
        if (!Utility.isEmpty(udfDetailList)) {
          for (int k = 0; k < udfDetailList.size(); k++) {
            udfDetail = (SysUserDefinedIndexDetail) udfDetailList.get(k);
            row = sheet.createRow(rowNum++);
            createCell(wb, row, (short) 0, udfDetail.getFieldName());


            for (int j = 0; j < udfDetailList.size(); j++) {
              docDetail = (DmsDocumentDetail) docDetailList.get(j);
              if (udfDetail.getID().equals(docDetail.getUserDefinedFieldDetailID())) {
                if (SysUserDefinedIndexDetail.DATE_FIELD.equals(udfDetail.getFieldType())) {
                  createCell(wb, row, (short) 1, TextUtility.formatTimestampToDate(docDetail.getDateValue()));
                  createCell(wb, row, (short) 2, TextUtility.formatTimestampToDate(docDetail.getToDateValue()));
                } else if (SysUserDefinedIndexDetail.NUMBER_FIELD.equals(udfDetail.getFieldType())) {
                  createCell(wb, row, (short) 1, TextUtility.formatDoubleObj(docDetail.getNumericValue()));
                  createCell(wb, row, (short) 2, TextUtility.formatDoubleObj(docDetail.getToNumericValue()));
                } else {
                  createCell(wb, row, (short) 1, docDetail.getFieldValue());
                  createCell(wb, row, (short) 2, docDetail.getToFieldValue());
                }
              }//end if
            }//end for
          }
        } //End of docDetail retrieval

        row = sheet.createRow(rowNum++); //empty row
      } else if (DmsOperationConstant.KEYWORD_SEARCH_OPERATION.equals(searchForm.getAdvSearchOpt())) { //Keyword Search
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.search_criteria"));
        row = sheet.createRow(rowNum++);
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "common.label.keyword_search"));
        createCell(wb, row, (short) 1, searchForm.getKeyword());
        row = sheet.createRow(rowNum++);
      }

      //search result
      row = sheet.createRow(rowNum++);
      createCell(wb, row, (short) 0, "Search Result");

      /* The label row */
      row = sheet.createRow(rowNum++);
      createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_D"));
      createCell(wb, row, (short) 1, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.location"));
      createCell(wb, row, (short) 2, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.document_type"));
      createCell(wb, row, (short) 3, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.columnheader.item_size"));
      createCell(wb, row, (short) 4, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "common.label.creator_name"));
      createCell(wb, row, (short) 5, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.columnheader.profile_name"));      
      createCell(wb, row, (short) 6, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.reference_no"));
      createCell(wb, row, (short) 7, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.description"));
      createCell(wb, row, (short) 8, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.columnheader.item_status"));
      createCell(wb, row, (short) 9, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.effective_date"));

      int nUdfRow = 10;
      if (!Utility.isEmpty(defaultProfileSettingList)) {
        for (int i = 0; i < totalFieldCount; i++) {
          DmsDefaultProfileSetting setting = ( (DmsDefaultProfileSetting) defaultProfileSettingList.get(i));
          createCell(wb, row, (short) nUdfRow++, setting.getFieldName());
        }
      }

      if (DmsOperationConstant.KEYWORD_SEARCH_OPERATION.equals(searchForm.getAdvSearchOpt())) {
        createCell(wb, row, (short) nUdfRow, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.user_defined_index"));
      } else {
        if (!Utility.isEmpty(docList)) {
          if (Utility.isEmpty(udfDetailList)) {
            DmsDocument tmpDocument = (DmsDocument) docList.get(0);
            searchForm.setUserDefinedFieldID(TextUtility.formatIntegerObj(tmpDocument.getUserDefinedFieldID()));
            udfDetailList = docRetrievalManager.getUDFDetailList(TextUtility.parseIntegerObj(searchForm.getUserDefinedFieldID()));
            searchForm.setUdfDetailList(udfDetailList);
          }

          //for (int l = udfDetailList.size() - 1; l >= 0; l--) {
          for (int l = 0; l < udfDetailList.size(); l++) {
            udfDetail = (SysUserDefinedIndexDetail) udfDetailList.get(l);
            createCell(wb, row, (short) (nUdfRow + l), udfDetail.getFieldName());
          }
        } //End of docDetail retrieval
      }
      /* End of label row */

      /* The result row */
      DmsDocument document = new DmsDocument();
      Hashtable docNameTable = new Hashtable();
      List allDocList = new ArrayList();
      allDocList.addAll(docList);

      /*for(int i=0;i<allDocList.size();i++){
       DmsDocument doc=(DmsDocument)allDocList.get(i);
       if(DmsDocument.COMPOUND_DOC_TYPE.equals(doc.getDocumentType())){
        DocumentOperationManager docOperationManager=new DocumentOperationManager(sessionContainer,conn);
        List subList=docOperationManager.getSubDocumentByParentID(doc.getID());
        allDocList.addAll(subList);
       }
     }*/

      PermissionManager permissionManager = sessionContainer.getPermissionManager();
      //String permission = (String)permissionManager.getPermission(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT, document.getID());
      //       if(permission.indexOf("R")>=0){

      for (int i = 0; i < allDocList.size(); i++) {
        document = (DmsDocument) allDocList.get(i);

        String permission = permissionManager.getPermission(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT, document.getID());
        if (permission.indexOf("R")>=0) {
          /*handle if the document is short cut, get the real document*/
          if (DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType())) {
            MtmDocumentRelationshipDAObject docRelationshipDAO = new MtmDocumentRelationshipDAObject(sessionContainer, conn);
            Integer targetDocID = docRelationshipDAO.getTargetDocIDByRelatedDocID(document.getID(), document.getDocumentType());
            if(!Utility.isEmpty(targetDocID)){
              DmsDocument targetDoc = docRetrievalManager.getDocument(targetDocID);
              /* Used to update the doc link name and type; Wont infulence the getDocumentProfileInfo() */
              targetDoc.setDocumentName(document.getDocumentName());
              /* not handle the shortcut to folder */
              if(!DmsDocument.FOLDER_TYPE.equals(targetDoc.getDocumentType())){
                targetDoc.setDocumentType(document.getDocumentType());
              }
              document = targetDoc;
            }
          }
          /*End of handle if the document is short cut, get the real document*/



          //only non folder type document add to the search result
          if (DmsDocument.DOCUMENT_TYPE.equals(document.getDocumentType()) || DmsDocument.COMPOUND_DOC_TYPE.equals(document.getDocumentType())||
            DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType()) || DmsDocument.PAPER_DOC_TYPE.equals(document.getDocumentType()) ||
            DmsDocument.EMAIL_DOC_TYPE.equals(document.getDocumentType()) || DmsDocument.FORM_DOC_TYPE.equals(document.getDocumentType()) ||
            DmsDocument.FLOW_DOC_TYPE.equals(document.getDocumentType())) {
            row = sheet.createRow(rowNum++);
            String name = document.getDocumentName();
            if (!docNameTable.containsKey(name)) {
              docNameTable.put(name, "0");
            } else {
              int exists = TextUtility.parseInteger( (String) docNameTable.get(name));
              docNameTable.put(name, TextUtility.formatInteger(++exists)); //update the existence
              /*
               * Update Code Start
               * Author			Jim.Zhou
               * Date			2006/05/16
               * Bug			#5373
               */
              if (name.indexOf('.')>-1) {
            	  name = name.substring(0,name.lastIndexOf('.')) + "(" + exists + ")" + name.substring(name.lastIndexOf('.')) ;
              } else {
                  name = name + "(" + exists + ")";
              }
              //name = name + "(" + exists + ")";
              /*
               * Update Code End
               */
              docNameTable.put(name, "0");
            }

            //get the document type display name
            String displayDocType = "";
            if (DmsDocument.DOCUMENT_TYPE.equals(document.getDocumentType())) {
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_D");
            } else if (DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType())) {
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_L");
            } else if (DmsDocument.COMPOUND_DOC_TYPE.equals(document.getDocumentType())) {
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_C");
            } else if (DmsDocument.PAPER_DOC_TYPE.equals(document.getDocumentType())){
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_H");
            } else if (DmsDocument.EMAIL_DOC_TYPE.equals(document.getDocumentType())){
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"dms.label.doc_type_E");
            } else if (DmsDocument.FORM_DOC_TYPE.equals(document.getDocumentType())){
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"dms.label.doc_type_F");
            } else if (DmsDocument.FLOW_DOC_TYPE.equals(document.getDocumentType())){
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(),"dms.label.doc_type_W");
            }
            

            createCell(wb, row, (short) 0, name);
            createCell(wb, row, (short) 1, docRetrievalManager.getLocationPath(document.getParentID()));
            createCell(wb, row, (short) 2, displayDocType);
            if(!DmsDocument.PAPER_DOC_TYPE.equals(document.getDocumentType())){
              if(DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType())){
              	MtmDocumentRelationshipDAObject docRelationshipDAO = new MtmDocumentRelationshipDAObject(sessionContainer, conn);
                Integer targetDocID = docRelationshipDAO.getTargetDocIDByRelatedDocID(document.getID(), document.getDocumentType());
                if(Utility.isEmpty(targetDocID)){
                  createCell(wb, row, (short) 3, "");
                }else{
                  createCell(wb, row, (short) 3, TextUtility.formatFileSize(document.getItemSize().intValue()));
                }
              }else{
                createCell(wb, row, (short) 3, TextUtility.formatFileSize(document.getItemSize().intValue()));
              }
            }else{
              createCell(wb, row, (short) 3, "");
            }
            String userName = UserInfoFactory.getUserFullName(document.getCreatorID());            
            createCell(wb, row, (short) 4, userName);          
            String udfName = docRetrievalManager.getUserDefinedTypeByDocumentID(document.getID());
            createCell(wb, row, (short) 5, udfName);            
            createCell(wb, row, (short) 6, document.getReferenceNo());
            createCell(wb, row, (short) 7, document.getDescription());
            createCell(wb, row, (short) 8, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_lock_" + document.getItemStatus()));

            //Effective date rangel
            String dateRange = "";
            dateRange = TextUtility.formatTimestampToDate(document.getEffectiveStartDate()) + "~ " + TextUtility.formatTimestampToDate(document.getEffectiveEndDate());
            createCell(wb, row, (short) 9, dateRange);

            nUdfRow = 10;
            //Common Profile
            if (!Utility.isEmpty(defaultProfileSettingList)) {
              for (int k = 0; k < totalFieldCount; k++) {
                String userDefValue = "";
                switch (k) {
                case 0:
                  userDefValue = document.getUserDef1();
                  break;
                case 1:
                  userDefValue = document.getUserDef2();
                  break;
                case 2:
                  userDefValue = document.getUserDef3();
                  break;
                case 3:
                  userDefValue = document.getUserDef4();
                  break;
                case 4:
                  userDefValue = document.getUserDef5();
                  break;
                case 5:
                  userDefValue = document.getUserDef6();
                  break;
                case 6:
                  userDefValue = document.getUserDef7();
                  break;
                case 7:
                  userDefValue = document.getUserDef8();
                  break;
                case 8:
                  userDefValue = document.getUserDef9();
                  break;
                case 9:
                  userDefValue = document.getUserDef10();
                  break;
                }
                if (Utility.isEmpty(userDefValue)) {
                  userDefValue = "";
                }
                createCell(wb, row, (short) nUdfRow++, userDefValue);
              }
            }

            //Use for List the target User Defined Fields Detail
            List resultUDFDetailList = new ArrayList();
            if (searchForm.getUserDefinedFieldID() != null) {
              searchForm.setUdfDetailList(udfDetailList);
            }

            List resultDocDetailList = docRetrievalManager.getDocumentDetailList(document.getID());
            if (!Utility.isEmpty(resultDocDetailList)) {
              if (DmsOperationConstant.KEYWORD_SEARCH_OPERATION.equals(searchForm.getAdvSearchOpt())) {
                SysUserDefinedIndex udfIndex = docRetrievalManager.getUserDefinedFieldByDocument(document);
                createCell(wb, row, (short) (nUdfRow++), udfIndex.getUserDefinedType());
              } else if (DmsOperationConstant.ATTR_SEARCH_OPERATION.equals(searchForm.getAdvSearchOpt())) {
                for (int k = 0; k < udfDetailList.size(); k++) {
                  udfDetail = (SysUserDefinedIndexDetail) udfDetailList.get(k);
                  for (int l = 0; l < resultDocDetailList.size(); l++) {
                    docDetail = (DmsDocumentDetail) resultDocDetailList.get(l);
                    if (udfDetail.getID().equals(docDetail.getUserDefinedFieldDetailID())) {
                      if (SysUserDefinedIndexDetail.DATE_FIELD.equals(udfDetail.getFieldType())) {
                        createCell(wb, row, (short) (nUdfRow++), TextUtility.formatTimestampToDate(docDetail.getDateValue()));
                      } else if (SysUserDefinedIndexDetail.NUMBER_FIELD.equals(udfDetail.getFieldType())) {
                        createCell(wb, row, (short) (nUdfRow++), TextUtility.formatDoubleObj(docDetail.getNumericValue()));
                      } else {
                        createCell(wb, row, (short) (nUdfRow++), docDetail.getFieldValue());
                      }
                      break;
                    }
                  }
                }
              }
            }
          } //end if folder
        }//end of check permission if
      } //End of Document result insert

      ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
      
      /*
       * Test Code Start
       */
      /*
      FileOutputStream fos= new FileOutputStream("c:\\exceltest.xls");
      wb.write(fos);
      fos.close();
      */
      /*
       * Test Code End
       */

      wb.write(byteOut);
      byte[] excelData = byteOut.toByteArray();
      byteOut.close();
      /* end of creating excel */

      //start of sending email, creating Zip
      String subject = "Search Result";
      String contentPart = "";
      String ID = "0";

      StringBuffer content = new StringBuffer("Attached please find the search criteria and search results ");
      //content.append(document.getDocumentName()).append("' is being created.\n\n");
      //content.append(contentPart);

      UserRecordDAObject userDAO = new UserRecordDAObject(sessionContainer, conn);
      UserRecord senderUser = (UserRecord) userDAO.getObjectByID(sessionContainer.getUserRecordID());

      //adding attachments to the emails
      String tempConvertedName = String.valueOf(System.currentTimeMillis());
      StringBuffer tempZipFile = new StringBuffer();
      DmsLocMaster locMaster = rootRetrievalManager.getTargetLocMasterByDocument(document);
      String locMasterPath = locMaster.getLocPath();
      log.debug("locMasterPath = " + locMasterPath);
      tempZipFile = tempZipFile.append(locMasterPath).append("/").append(tempConvertedName).append(".zip");
      FileOutputStream f = new FileOutputStream(tempZipFile.toString());
//      CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());
//      ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(csum));
      /*
       * Update Code Start
       * Author			Jim.Zhou
       * Date			2006/04/12
       * Bug			#4820
       */
      DocumentRetrievalManager docRetrieval = new DocumentRetrievalManager(sessionContainer,conn);
      org.apache.tools.zip.ZipOutputStream out= new ZipOutputStream(new FileOutputStream(tempZipFile.toString()));
      //log.debug("Ecording:"+SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_ZIP_FILE_DEFAULT_ENCODING));
      out.setEncoding(docRetrieval.getZipFileDefaultEncode());
      /*
       * Update Code End
       */
      //log.debug("Method:"+ZipOutputStream.DEFLATED);
      out.setMethod(ZipOutputStream.DEFLATED);
      String convertedName = "";
 

      docNameTable = new Hashtable();
      /*
       * Update Code Start
       * Author				Jim.Zhou
       * Date				2006/04/10
       * Bug				#4820
       */
      boolean zipFailedAddedFlag = false;
      boolean zipArchivedFileFailedAddedFlag = false;
      /*
       * Update Code End
       */
      for (int i = 0; i < docList.size(); i++) {
        document = (DmsDocument) docList.get(i);

        String permission1 = permissionManager.getPermission(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT, document.getID());
        if(permission1.indexOf("R")>=0){

          /*handle if the document is short cut, get the real document*/
          if (DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType())) {
            MtmDocumentRelationshipDAObject docRelationshipDAO = new MtmDocumentRelationshipDAObject(sessionContainer, conn);
            Integer targetDocID = docRelationshipDAO.getTargetDocIDByRelatedDocID(document.getID(), document.getDocumentType());
            if(!Utility.isEmpty(targetDocID)){
              DmsDocument targetDoc = docRetrievalManager.getDocument(targetDocID);
              /* Used to update the doc link name and type; Wont infulence the getDocumentProfileInfo() */
              targetDoc.setDocumentName(document.getDocumentName());

              //if short cut document is no postfix then add the source document's postfix
              DmsDocument targetDocTemp =docRetrievalManager.getRelationshipTargetDocument((document).getID(),(document).getDocumentType());
              if(document.getDocumentName().indexOf(".") < 0 && targetDocTemp.getDocumentName().indexOf(".")>0){
                String documentNameTemp = targetDocTemp.getDocumentName();
                int postfixLocation = documentNameTemp.lastIndexOf(".");
                String postfix = documentNameTemp.substring(postfixLocation,documentNameTemp.length());
                targetDoc.setDocumentName(document.getDocumentName()+ postfix);
              }

              /*not handle short to folder*/
              if(!DmsDocument.FOLDER_TYPE.equals(targetDoc.getDocumentType())){
                targetDoc.setDocumentType(document.getDocumentType());
              }
              document = targetDoc;
            }
          }
          /*End of handle if the document is short cut, get the real document*/

          //add to document that is not folder type into the zip file
          if (DmsDocument.DOCUMENT_TYPE.equals(document.getDocumentType())||DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType())) {
            //String name = document.getDocumentName();
//            String name = TextUtility.getURLEncodeInUTF8(document.getDocumentName());
            String name = document.getDocumentName();                  

            if (!docNameTable.containsKey(name)) {
              docNameTable.put(name, "0");
            } else {
              int exists = TextUtility.parseInteger( (String) docNameTable.get(name));
              docNameTable.put(name, TextUtility.formatInteger(++exists)); //update the existence
              /*
               * Update Code Start
               * Author			Jim.Zhou
               * Date			2006/05/16
               * Bug			#5373
               */
              if (name.indexOf('.')>-1) {
            	  name = name.substring(0,name.lastIndexOf('.')) + "(" + exists + ")" + name.substring(name.lastIndexOf('.')) ;
              } else {
            	  name = name + "(" + exists + ")";
              }
              //name = name + "(" + exists + ")";
              /*
               * Update Code End
               */
              docNameTable.put(name, "0");
            }
            DmsVersion topVersion = docRetrievalManager.getTopVersionByDocumentID(document.getID());
            DmsContent topContent = docRetrievalManager.getContentByContentID(topVersion.getContentID());
 
            //for zip
            InputStream in = null;
            try {
              if(!DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType())){
                in = dmsContentManager.readDmsDocumentStoreContent(document,topContent);
                ZipEntry zipEntry = new ZipEntry(name);
                out.putNextEntry(zipEntry); //ZipException ??? why?
                int c;
                while ( (c = in.read()) != -1) {
                  out.write(c);
                }
              }else{
              	MtmDocumentRelationshipDAObject docRelationshipDAO = new MtmDocumentRelationshipDAObject(sessionContainer, conn);
                Integer targetDocID = docRelationshipDAO.getTargetDocIDByRelatedDocID(document.getID(), document.getDocumentType());
                if(!Utility.isEmpty(targetDocID)){
                  in = dmsContentManager.readDmsDocumentStoreContent(document,topContent);
                  out.putNextEntry(new ZipEntry(name));
                  int c;
                  while ( (c = in.read()) != -1) {
                    out.write(c);
                  }
                }
              }
            } catch (ContentStoreException cse) {
              log.error(cse);
              /*
               * Update Code Start
               * Author				Jim.Zhou
               * Date				2006/04/10
               * Bug				#4820
               */
              /*
               * no error message if physical file not found. (lee 06/11/28 EIP-952)
              if(DmsVersion.ARCHIVED_STATUS.equals(document.getItemStatus())){
            	if(!zipArchivedFileFailedAddedFlag){
                  addError(request,DmsErrorConstant.RESULT_ZIP_ARCHIVED_FILE_FAILED);
                  zipArchivedFileFailedAddedFlag = true;
            	}
              }else{
            	if(!zipFailedAddedFlag){
                  addError(request, DmsErrorConstant.RESULT_ZIP_FAILED);
                  zipFailedAddedFlag = true;
            	}
              }
              */
              /*
               * Update Code End
               */

            }
            finally {
              try {
                in.close();
              } catch (Exception ignore) {} finally {
                in = null;
              }
            }
          } //end if
          if ((DmsDocument.COMPOUND_DOC_TYPE.equals(document.getDocumentType()) ||
          		(DmsDocument.PAPER_DOC_TYPE.equals(document.getDocumentType()) && hasSubDocument(document,request)) ||
               DmsDocument.EMAIL_DOC_TYPE.equals(document.getDocumentType()) || 
               DmsDocument.FORM_DOC_TYPE.equals(document.getDocumentType()) ||
               DmsDocument.FLOW_DOC_TYPE.equals(document.getDocumentType())) 
               && !"R".equals(document.getItemStatus())){
            InputStream inputStream = null;
            InputStream dataStream = null;
            //String zipfilename = document.getDocumentName() + ".zip";
//            String zipfilename = TextUtility.getURLEncodeInUTF8(document.getDocumentName())+".zip";
            String zipfilename = DocumentRetrievalManager.getEncodeStringByEncodeCode(document.getDocumentName(),SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_ZIP_FILE_DEFAULT_ENCODING))+".zip";                  
            StringBuffer comZipFile = new StringBuffer();
            comZipFile = comZipFile.append(locMasterPath).append("/").append(zipfilename);

            try {
              FileOutputStream fileOutputStream = new FileOutputStream(comZipFile.toString());
//              CheckedOutputStream cosm = new CheckedOutputStream(fileOutputStream, new Adler32());
//              ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(cosm));
              ZipOutputStream zos= new ZipOutputStream(new FileOutputStream(comZipFile.toString()));                     
              /*
               * Update Code Start
               * Author			Jim.Zhou
               * Date			2006/04/12
               * Bug			#4820
               */
              zos.setEncoding(docRetrieval.getZipFileDefaultEncode());
              /*
               * Update Code End
               */
              DocumentOperationManager docOperationManager = new DocumentOperationManager(sessionContainer, conn);
              //List list=new ArrayList();
              Integer targetID = document.getID();
              Integer contentID = null;
              DmsVersion dmsVersion = new DmsVersion();
              MtmDocumentRelationshipDAObject docRelationshipDAO = new MtmDocumentRelationshipDAObject(sessionContainer, conn);
              List list = docOperationManager.getSubDocumentByParentID(document.getID());
              if(DmsDocument.COMPOUND_DOC_TYPE.equals(document.getDocumentType()) || 
                 DmsDocument.EMAIL_DOC_TYPE.equals(document.getDocumentType()) ||
                 DmsDocument.FORM_DOC_TYPE.equals(document.getDocumentType()) || 
                 DmsDocument.FLOW_DOC_TYPE.equals(document.getDocumentType())){
                list.add(document);
              }
              //Object[] putStream=new Object[list.size()];
              if (!Utility.isEmpty(list)) {
            	  /*
                   * joan.xiong add code for bug EIP-533 by 2006/10/23
                   */
                  List tempCurList = new ArrayList();
            	  for(int j=0;j<list.size();j++){
            		  String permission = sessionContainer.getPermissionManager().getPermission(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT, ((DmsDocument)list.get(j)).getID());
                	  if(permission.indexOf("R")>=0){
                		  tempCurList.add(list.get(j));
                	  }
            	  }
            	  list = tempCurList;
                  /*
                   * joan.xiong add code end
                   */
                for (int j = 0; j < list.size(); j++) {
                  DmsDocument dmsDocument = (DmsDocument) list.get(j);
                  //String fName = dmsDocument.getDocumentName();
//                  String fName = TextUtility.getURLEncodeInUTF8(dmsDocument.getDocumentName());
                  String fName = dmsDocument.getDocumentName();                  

                  DmsVersion sVersion = docRetrievalManager.getTopVersionByDocumentID(dmsDocument.getID());
                  contentID = sVersion.getContentID();
                  if (DmsDocument.DOCUMENT_LINK.equals(dmsDocument.getDocumentType())) {
                    Integer targetDocID = docRelationshipDAO.getTargetDocIDByRelatedDocID(dmsDocument.getID(), dmsDocument.getDocumentType());
                    if(!Utility.isEmpty(targetDocID)){
                      DmsDocument targetDoc = docRetrievalManager.getDocument(targetDocID);
                      /* Used to update the doc link name and type; Wont infulence the getDocumentProfileInfo() */
                      if (targetDoc != null) {
                        targetDoc.setDocumentName(dmsDocument.getDocumentName());
                        targetDoc.setDocumentType(dmsDocument.getDocumentType());
                        //update the doc ID for shortcut linkage
                        targetID = targetDocID;
                        dmsDocument = targetDoc;
                        //update the real link document version
                        sVersion = docRetrievalManager.getTopVersionByDocumentID(targetID);
                        contentID = sVersion.getContentID();
                      } else {
                        document.setRecordStatus(GlobalConstant.RECORD_STATUS_INACTIVE);
                      }
                    }
                  }
                  if (!GlobalConstant.RECORD_STATUS_INACTIVE.equals(document.getRecordStatus())) {
                    DmsContent docContent = docRetrievalManager.getContentByContentID(contentID);
                    dataStream = dmsContentManager.readDmsDocumentStoreContent(dmsDocument,docContent);
                    //putStream[j]=dataStream;
                    ZipEntry theEntry = new ZipEntry(fName);
                    zos.putNextEntry(theEntry);

                    byte[] buffer = new byte[8192];
                    int length = -1;
                    inputStream = dataStream;
                    while ( (length = inputStream.read(buffer, 0, 8192)) != -1) {
                      zos.write(buffer, 0, length);
                    }
                  }
                }
                //inputStream=putStream.
              }
              zos.flush();
              zos.close();
            } catch (Exception e) {
              log.error(e, e);
              /*
               * Update Code Start
               * Author			Jim.Zhou
               * Date			2006/04/12
               * Bug			#4820
               */
              //throw new ApplicationException(com.dcivision.framework.ErrorConstant.COMMON_FATAL_ERROR, e);
              /*
               * Update Code End
               */
            } finally {
            /*
             * Update Code Start
             * Author			Jim.Zhou
             * Date			2006/04/12
             * Bug			#4820
             */
              try {
            	if (inputStream!=null){
            		inputStream.close();
            	}
              } catch (IOException ignore) {
                inputStream = null;
              }
	          /*
	           * Update Code End
	           */
            }

            BufferedInputStream in = new BufferedInputStream(new FileInputStream(comZipFile.toString()));
            //InputStream in = null;
            try {
              out.putNextEntry(new ZipEntry(zipfilename));
              int c;
              while ( (c = in.read()) != -1) {
                out.write(c);
              }
            } catch (Exception cse) {
              log.error(cse);
              addError(request, DmsErrorConstant.RESULT_ZIP_FAILED);
            } finally {
              //try {} catch (Exception ignore) {} finally { in = null; }
              try {
                in.close();
              } catch (Exception ignore) {} finally {
                in = null;
              }
            }
          }

        }//end of check permisssion if
      } //end for

      //adding the excel file to the zip
      InputStream in = null;
      try {
        in = new ByteArrayInputStream(excelData);
        out.putNextEntry(new ZipEntry("SEARCH_RESULTS.xls"));
        int c;
        while ( (c = in.read()) != -1) {
          out.write(c);
        }
      } catch (Exception e) {
        log.error(e);
      } finally {
        try {
          in.close();
        } catch (Exception ignore) {} finally {
          in = null;
        }
        try {
          out.close();
        } catch (Exception ignore) {} finally {
          out = null;
        }
      }

      /*- by harry on 21/05/2003, use save as instead
             EmailDeliveryMessage msg = new EmailDeliveryMessage();
             msg.addAttachment("result_files.zip", zipByte);
             msg.addAttachment("SEARCH_RESULTS.xls", excelData);
             msg.setSubject(subject);
             msg.setMailContent(content.toString());
             msg.setSender(new GenericAddress(senderUser.getEmail() != null ? senderUser.getEmail() : "", senderUser.getLastName() + " " + senderUser.getFirstName()));
             msg.addToRecipient(new GenericAddress(senderUser.getEmail()));
             if (msg.getToRecipientList().size() > 0) {
        NotificationWay emailNotification = NotificationWayFactory.getNotificationInstance(NotificationWay.EMAIL_NOTIFICATION_INSTANCE);
        emailNotification.addDeliveryMessage((DeliveryMessage) msg);
        emailNotification.send();
             }
       */
      //end of sending email

      // Pass the temp zip file name through session.
      /*
       * Update Code Start
       * Author			Jim.Zhou
       * Date			2006/04/12
       * Bug			#4820
       */
      //if (zipFailedAddedFlag || zipArchivedFileFailedAddedFlag){
          request.getSession().setAttribute("zipExportFileName", tempZipFile.toString());
      //}
      /*
       * Update Code End
       */
      //request.setAttribute(this.m_sListName, docList);
      sessionContainer = null;
      docRetrievalManager.release();
    } catch (Exception e) {
      log.error("Search error.", e);
    } finally {
      conn = null;
    }
  }

  /**
   * advance search document with import file
   */
  public void exportExcelAdvance(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);

    RootRetrievalManager rootRetrievalManager = new RootRetrievalManager(sessionContainer, conn);
    ListDmsDocumentForm searchForm = (ListDmsDocumentForm) form;
    List defaultProfileSettingList = new ArrayList();
    int totalFieldCount = 0;
    try {
      searchForm.setSearchResultOpt(DmsOperationConstant.SEARCH_RESULT_ALL);
      List docList = this.getExportResultListData(mapping, searchForm, request, response);
      log.debug("completed search result list= " + docList.size());

      /* creating excel file */
      HSSFWorkbook wb = new HSSFWorkbook();
      HSSFSheet sheet = wb.createSheet("result");
      sheet.setDefaultColumnWidth( (short) 18);
      short rowNum = 0;
      HSSFRow row = sheet.createRow(rowNum++);

      //Use for List the target User Defined Fields Detail
      List udfDetailList = new ArrayList();
      SysUserDefinedIndexDetail udfDetail = new SysUserDefinedIndexDetail();
      DmsDocumentDetail docDetail = new DmsDocumentDetail();
      if (searchForm.getUserDefinedFieldID() != null) {
        udfDetailList = docRetrievalManager.getUDFDetailList(TextUtility.parseIntegerObj(searchForm.getUserDefinedFieldID()));
        searchForm.setUdfDetailList(udfDetailList);
      }

      // search criteria for Advance Search
      if (DmsOperationConstant.ATTR_SEARCH_OPERATION.equals(searchForm.getAdvSearchOpt())) {
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.search_criteria"));
        row = sheet.createRow(rowNum++);
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_D"));
        createCell(wb, row, (short) 1, searchForm.getDocumentName());
        row = sheet.createRow(rowNum++);
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.effective_date"));
        createCell(wb, row, (short) 1, searchForm.getEffectiveStartDate());
        createCell(wb, row, (short) 2, searchForm.getEffectiveEndDate());
        row = sheet.createRow(rowNum++);
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.description"));
        createCell(wb, row, (short) 1, searchForm.getDescription());
        row = sheet.createRow(rowNum++);
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.reference_no"));
        createCell(wb, row, (short) 1, searchForm.getReferenceNo());

        //Common profiles
        defaultProfileSettingList = (List) request.getSession().getServletContext().getAttribute("DMS_DEF_PROFILE");
        totalFieldCount = Integer.parseInt(com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.DMS_DEFAULT_PROFILE_FIELD_COUNT));
        if (!Utility.isEmpty(defaultProfileSettingList)) {
          for (int i = 0; i < totalFieldCount; i++) {
            row = sheet.createRow(rowNum++);
            DmsDefaultProfileSetting setting = ( (DmsDefaultProfileSetting) defaultProfileSettingList.get(i));
            createCell(wb, row, (short) 0, setting.getFieldName());
            String userDefValue = "";
            switch (i) {
            case 0:
              userDefValue = searchForm.getUserDef1();
              break;
            case 1:
              userDefValue = searchForm.getUserDef2();
              break;
            case 2:
              userDefValue = searchForm.getUserDef3();
              break;
            case 3:
              userDefValue = searchForm.getUserDef4();
              break;
            case 4:
              userDefValue = searchForm.getUserDef5();
              break;
            case 5:
              userDefValue = searchForm.getUserDef6();
              break;
            case 6:
              userDefValue = searchForm.getUserDef7();
              break;
            case 7:
              userDefValue = searchForm.getUserDef8();
              break;
            case 8:
              userDefValue = searchForm.getUserDef9();
              break;
            case 9:
              userDefValue = searchForm.getUserDef10();
              break;
            }
            if (Utility.isEmpty(userDefValue)) {
              userDefValue = "";
            }
            createCell(wb, row, (short) 1, userDefValue);
          }
        }

        List docDetailList = searchForm.getDocumentDetails();
        if (!Utility.isEmpty(docDetailList)) {
          docDetail = (DmsDocumentDetail) docDetailList.get(0);
        }


        row = sheet.createRow(rowNum++);
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.user_defined_index"));
        SysUserDefinedIndex udfIndex = docRetrievalManager.getUDF(docDetail.getUserDefinedFieldID());
        if (udfIndex != null) {
          createCell(wb, row, (short) 1, udfIndex.getUserDefinedType());
        }

        //Loop the UDF and input search criteria
        if (!Utility.isEmpty(udfDetailList)) {
          for (int k = 0; k < udfDetailList.size(); k++) {
            udfDetail = (SysUserDefinedIndexDetail) udfDetailList.get(k);
            row = sheet.createRow(rowNum++);
            createCell(wb, row, (short) 0, udfDetail.getFieldName());


            for (int j = 0; j < udfDetailList.size(); j++) {
              docDetail = (DmsDocumentDetail) docDetailList.get(j);
              if (udfDetail.getID().equals(docDetail.getUserDefinedFieldDetailID())) {
                if (SysUserDefinedIndexDetail.DATE_FIELD.equals(udfDetail.getFieldType())) {
                  createCell(wb, row, (short) 1, TextUtility.formatTimestampToDate(docDetail.getDateValue()));
                  createCell(wb, row, (short) 2, TextUtility.formatTimestampToDate(docDetail.getToDateValue()));
                } else if (SysUserDefinedIndexDetail.NUMBER_FIELD.equals(udfDetail.getFieldType())) {
                  createCell(wb, row, (short) 1, TextUtility.formatDoubleObj(docDetail.getNumericValue()));
                  createCell(wb, row, (short) 2, TextUtility.formatDoubleObj(docDetail.getToNumericValue()));
                } else {
                  createCell(wb, row, (short) 1, docDetail.getFieldValue());
                  createCell(wb, row, (short) 2, docDetail.getToFieldValue());
                }
              }//end if
            }//end for
          }
        } //End of docDetail retrieval

        row = sheet.createRow(rowNum++); //empty row
      } else if (DmsOperationConstant.KEYWORD_SEARCH_OPERATION.equals(searchForm.getAdvSearchOpt())) { //Keyword Search
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.search_criteria"));
        row = sheet.createRow(rowNum++);
        createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "common.label.keyword_search"));
        createCell(wb, row, (short) 1, searchForm.getKeyword());
        row = sheet.createRow(rowNum++);
      }

      //search result
      row = sheet.createRow(rowNum++);
      createCell(wb, row, (short) 0, "Search Result");

      /* The label row */
      row = sheet.createRow(rowNum++);
      createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_D"));
      createCell(wb, row, (short) 1, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.location"));
      createCell(wb, row, (short) 2, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.document_type"));
      createCell(wb, row, (short) 3, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.columnheader.item_size"));
      createCell(wb, row, (short) 4, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "common.label.creator_name"));
      createCell(wb, row, (short) 5, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.columnheader.profile_name"));      
      createCell(wb, row, (short) 6, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.reference_no"));
      createCell(wb, row, (short) 7, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.description"));
      createCell(wb, row, (short) 8, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.columnheader.item_status"));
      createCell(wb, row, (short) 9, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.effective_date"));

      int nUdfRow = 10;
      if (!Utility.isEmpty(defaultProfileSettingList)) {
        for (int i = 0; i < totalFieldCount; i++) {
          DmsDefaultProfileSetting setting = ( (DmsDefaultProfileSetting) defaultProfileSettingList.get(i));
          createCell(wb, row, (short) nUdfRow++, setting.getFieldName());
        }
      }

      if (DmsOperationConstant.KEYWORD_SEARCH_OPERATION.equals(searchForm.getAdvSearchOpt())) {
        createCell(wb, row, (short) nUdfRow, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.user_defined_index"));
      } else {
        if (!Utility.isEmpty(docList)) {
          if (Utility.isEmpty(udfDetailList)) {
            DmsDocument tmpDocument = (DmsDocument) docList.get(0);
            searchForm.setUserDefinedFieldID(TextUtility.formatIntegerObj(tmpDocument.getUserDefinedFieldID()));
            udfDetailList = docRetrievalManager.getUDFDetailList(TextUtility.parseIntegerObj(searchForm.getUserDefinedFieldID()));
            searchForm.setUdfDetailList(udfDetailList);
          }

          //for (int l = udfDetailList.size() - 1; l >= 0; l--) {
          for (int l = 0; l < udfDetailList.size(); l++) {
            udfDetail = (SysUserDefinedIndexDetail) udfDetailList.get(l);
            createCell(wb, row, (short) (nUdfRow + l), udfDetail.getFieldName());
          }
        } //End of docDetail retrieval
      }
      /* End of label row */

      /* The result row */
      DmsDocument document = new DmsDocument();
      Hashtable docNameTable = new Hashtable();
      List allDocList = new ArrayList();
      allDocList.addAll(docList);

      PermissionManager permissionManager = sessionContainer.getPermissionManager();
      //String permission = (String)permissionManager.getPermission(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT, document.getID());
      //       if(permission.indexOf("R")>=0){

      for (int i = 0; i < allDocList.size(); i++) {
        document = (DmsDocument) allDocList.get(i);

        String permission = permissionManager.getPermission(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT, document.getID());
        if (permission.indexOf("R")>=0) {
          /*handle if the document is short cut, get the real document*/
          if (DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType())) {
            MtmDocumentRelationshipDAObject docRelationshipDAO = new MtmDocumentRelationshipDAObject(sessionContainer, conn);
            Integer targetDocID = docRelationshipDAO.getTargetDocIDByRelatedDocID(document.getID(), document.getDocumentType());
            if(!Utility.isEmpty(targetDocID)){
              DmsDocument targetDoc = docRetrievalManager.getDocument(targetDocID);
              /* Used to update the doc link name and type; Wont infulence the getDocumentProfileInfo() */
              targetDoc.setDocumentName(document.getDocumentName());
              /* not handle the shortcut to folder */
              if(!DmsDocument.FOLDER_TYPE.equals(targetDoc.getDocumentType())){
                targetDoc.setDocumentType(document.getDocumentType());
              }
              document = targetDoc;
            }
          }
          /*End of handle if the document is short cut, get the real document*/



          //only non folder type document add to the search result
          if (DmsDocument.DOCUMENT_TYPE.equals(document.getDocumentType()) || DmsDocument.COMPOUND_DOC_TYPE.equals(document.getDocumentType())||
              DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType()) || DmsDocument.PAPER_DOC_TYPE.equals(document.getDocumentType()) ||
              DmsDocument.EMAIL_DOC_TYPE.equals(document.getDocumentType()) || DmsDocument.FORM_DOC_TYPE.equals(document.getDocumentType()) ||
              DmsDocument.FLOW_DOC_TYPE.equals(document.getDocumentType())) {
            row = sheet.createRow(rowNum++);
            String name = document.getDocumentName();
            if (!docNameTable.containsKey(name)) {
              docNameTable.put(name, "0");
            } else {
              int exists = TextUtility.parseInteger( (String) docNameTable.get(name));
              docNameTable.put(name, TextUtility.formatInteger(++exists)); //update the existence
              /*
               * Update Code Start
               * Author			Jim.Zhou
               * Date			2006/05/16
               * Bug			#5373
               */
              if (name.indexOf('.')>-1) {
            	  name = name.substring(0,name.lastIndexOf('.')) + "(" + exists + ")" + name.substring(name.lastIndexOf('.'));
              } else {
            	  name = name + "(" + exists + ")";
              }
              //name = name + "(" + exists + ")";
              /*
               * Update Code End
               */
              docNameTable.put(name, "0");
            }

            //get the document type display name
            String displayDocType = "";
            if (DmsDocument.DOCUMENT_TYPE.equals(document.getDocumentType())) {
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_D");
            } else if (DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType())) {
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_L");
            } else if (DmsDocument.COMPOUND_DOC_TYPE.equals(document.getDocumentType())) {
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_C");
            } else if (DmsDocument.PAPER_DOC_TYPE.equals(document.getDocumentType())){
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_H");
            } else if (DmsDocument.EMAIL_DOC_TYPE.equals(document.getDocumentType())){
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_E");
            } else if (DmsDocument.FORM_DOC_TYPE.equals(document.getDocumentType())){
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_F");
            } else if (DmsDocument.FLOW_DOC_TYPE.equals(document.getDocumentType())){
              displayDocType = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_type_W");
            }

            createCell(wb, row, (short) 0, name);
            createCell(wb, row, (short) 1, docRetrievalManager.getLocationPath(document.getParentID()));
            createCell(wb, row, (short) 2, displayDocType);
            if(!DmsDocument.PAPER_DOC_TYPE.equals(document.getDocumentType())){
              if(DmsDocument.DOCUMENT_LINK.equals(document.getDocumentType())){
                MtmDocumentRelationshipDAObject docRelationshipDAO = new MtmDocumentRelationshipDAObject(sessionContainer, conn);
                Integer targetDocID = docRelationshipDAO.getTargetDocIDByRelatedDocID(document.getID(), document.getDocumentType());
                if(Utility.isEmpty(targetDocID)){
                  createCell(wb, row, (short) 3, "");
                }else{
                  createCell(wb, row, (short) 3, TextUtility.formatFileSize(document.getItemSize().intValue()));
                }
              }else{
                createCell(wb, row, (short) 3, TextUtility.formatFileSize(document.getItemSize().intValue()));
              }
            }else{
              createCell(wb, row, (short) 3, "");
            }
            String userName = UserInfoFactory.getUserFullName(document.getCreatorID());            
            createCell(wb, row, (short) 4, userName);
            String udfName = docRetrievalManager.getUserDefinedTypeByDocumentID(document.getID());
            createCell(wb, row, (short) 5, udfName);            
            createCell(wb, row, (short) 6, document.getReferenceNo());
            createCell(wb, row, (short) 7, document.getDescription());
            createCell(wb, row, (short) 8, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.doc_lock_" + document.getItemStatus()));

            //Effective date rangel
            String dateRange = "";
            dateRange = TextUtility.formatTimestampToDate(document.getEffectiveStartDate()) + "~ " + TextUtility.formatTimestampToDate(document.getEffectiveEndDate());
            createCell(wb, row, (short) 9, dateRange);

            nUdfRow = 10;
            //Common Profile
            if (!Utility.isEmpty(defaultProfileSettingList)) {
              for (int k = 0; k < totalFieldCount; k++) {
                String userDefValue = "";
                switch (k) {
                case 0:
                  userDefValue = document.getUserDef1();
                  break;
                case 1:
                  userDefValue = document.getUserDef2();
                  break;
                case 2:
                  userDefValue = document.getUserDef3();
                  break;
                case 3:
                  userDefValue = document.getUserDef4();
                  break;
                case 4:
                  userDefValue = document.getUserDef5();
                  break;
                case 5:
                  userDefValue = document.getUserDef6();
                  break;
                case 6:
                  userDefValue = document.getUserDef7();
                  break;
                case 7:
                  userDefValue = document.getUserDef8();
                  break;
                case 8:
                  userDefValue = document.getUserDef9();
                  break;
                case 9:
                  userDefValue = document.getUserDef10();
                  break;
                }
                if (Utility.isEmpty(userDefValue)) {
                  userDefValue = "";
                }
                createCell(wb, row, (short) nUdfRow++, userDefValue);
              }
            }

            //Use for List the target User Defined Fields Detail
            List resultUDFDetailList = new ArrayList();
            if (searchForm.getUserDefinedFieldID() != null) {
              searchForm.setUdfDetailList(udfDetailList);
            }

            List resultDocDetailList = docRetrievalManager.getDocumentDetailList(document.getID());
            if (!Utility.isEmpty(resultDocDetailList)) {
              if (DmsOperationConstant.KEYWORD_SEARCH_OPERATION.equals(searchForm.getAdvSearchOpt())) {
                SysUserDefinedIndex udfIndex = docRetrievalManager.getUserDefinedFieldByDocument(document);
                createCell(wb, row, (short) (nUdfRow++), udfIndex.getUserDefinedType());
              } else if (DmsOperationConstant.ATTR_SEARCH_OPERATION.equals(searchForm.getAdvSearchOpt())) {
                for (int k = 0; k < udfDetailList.size(); k++) {
                  udfDetail = (SysUserDefinedIndexDetail) udfDetailList.get(k);
                  for (int l = 0; l < resultDocDetailList.size(); l++) {
                    docDetail = (DmsDocumentDetail) resultDocDetailList.get(l);
                    if (udfDetail.getID().equals(docDetail.getUserDefinedFieldDetailID())) {
                      if (SysUserDefinedIndexDetail.DATE_FIELD.equals(udfDetail.getFieldType())) {
                        createCell(wb, row, (short) (nUdfRow++), TextUtility.formatTimestampToDate(docDetail.getDateValue()));
                      } else if (SysUserDefinedIndexDetail.NUMBER_FIELD.equals(udfDetail.getFieldType())) {
                        createCell(wb, row, (short) (nUdfRow++), TextUtility.formatDoubleObj(docDetail.getNumericValue()));
                      } else {
                        createCell(wb, row, (short) (nUdfRow++), docDetail.getFieldValue());
                      }
                      break;
                    }
                  }
                }
              }
            }
          } //end if folder
        }//end of check permission if
      } //End of Document result insert

      ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
      wb.write(byteOut);

      DmsLocMaster locMaster = rootRetrievalManager.getTargetLocMasterByDocument(document);
      String locMasterPath = locMaster.getLocPath();

      byte[] excelData = byteOut.toByteArray();
      String path = locMasterPath+"/excel"+Math.random()+".xls";
      FileOutputStream f=new FileOutputStream(path);
      InputStream in = null;
      try {
        in = new ByteArrayInputStream(excelData);
        int c;
        while ( (c = in.read()) != -1) {
          f.write(c);
        }
      } catch (Exception e) {
        log.error(e);
      } finally {
        try {
          in.close();
        } catch (Exception ignore) {} finally {
          in = null;
        }
        try {
          f.close();
        } catch (Exception ignore) {} finally {
          f = null;
        }
      }
      request.getSession().setAttribute("exlExportFileName",path );
      byteOut.close();
      sessionContainer = null;
      docRetrievalManager.release();
    } catch (Exception e) {
      log.error("Search error.", e);
    } finally {
      conn = null;
    }
  }

  /**
   * bulk search document with import file
   */
  public List bulkSearchDocument(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    ListDmsDocumentForm searchForm = (ListDmsDocumentForm) form;
    List docList = new ArrayList();
    List searchObjectList = new ArrayList();
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    DocumentValidateManager docValidateManager = new DocumentValidateManager(sessionContainer, conn);

    try {
      String rootID = searchForm.getRootID();
      String parentID = searchForm.getParentID();
      String[] searchFolder = searchForm.getSearchFolder();
      List targetRootIDs = Utility.getList(searchFolder);
      FormFile formFile = null;
      InputStream inputStream = null;
      ListDmsDocumentForm searchObject = null;

      formFile = searchForm.getUploadFile();
      if (formFile != null && formFile.getFileSize() > 0) {
        log.debug("formFile size = " + formFile.getFileSize());
        inputStream = formFile.getInputStream();
        searchObjectList = readImportExcel(request, inputStream, rootID);
        request.getSession().setAttribute("DMS_BULK_SEARCH_LIST", searchObjectList);
        log.debug("search Object list size: " + searchObjectList.size());
      } else { //check the session for upload file path
        searchObjectList = (List) request.getSession().getAttribute("DMS_BULK_SEARCH_LIST");
      }

      // check duplicate name of same level if config file defined
      docValidateManager.checkSearchCriteriaExistence(searchObjectList);
      docList = docRetrievalManager.searchDocumentByImportFile(searchForm, searchObjectList, targetRootIDs);
    } catch (IOException ioe) {
      log.error(ioe, ioe);
    } finally {
      conn = null;
      sessionContainer = null;
      docRetrievalManager.release();
      docValidateManager.release();
    }
    return docList;
  }

  private List readImportExcel(HttpServletRequest request, InputStream fileIn,
                               String rootID) throws ApplicationException {
    List searchObjectList = new ArrayList();
    log.debug("reading import excel file");
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    try {
      if (fileIn != null) {
        HSSFWorkbook wb = new HSSFWorkbook(fileIn);
        HSSFSheet sheet = wb.getSheetAt(0);
        HSSFRow row = null;
        HSSFCell cell = null;
        HSSFCell tmpCell = null;
        String[] criteria = null;
        String value = "";

        HSSFRow firstRow = sheet.getRow( (short) 0); //first row
        criteria = new String[firstRow.getLastCellNum()];
        for (int i = 0; i < firstRow.getLastCellNum(); i++) {

          cell = firstRow.getCell( (short) i);
          if (cell != null) {
            int cellType = cell.getCellType();

            if (cellType == HSSFCell.CELL_TYPE_STRING) {
              int open = cell.getStringCellValue().trim().lastIndexOf("[");
              int close = cell.getStringCellValue().trim().lastIndexOf("]");
              if (open >= 0 && close >= 0) {
                //log.debug( cell.getStringCellValue().trim().substring(open+1,close));
                criteria[i] = cell.getStringCellValue().trim().substring(open +
                  1, close);
              } else {
                //log.debug("firstRow: 0 cell: " + i + " : " +  cell.getStringCellValue().trim());
                criteria[i] = cell.getStringCellValue().trim();
              }
            }
          } else {
            //log.debug("blank in firstRow:   0  cell: " + i);
            criteria[i] = "";
          }
        }
        for (int i = 0; i < criteria.length; i++) {
          log.debug(criteria[i]);
        }

        for (int j = 1; j <= sheet.getLastRowNum(); j++) { //start from 2 row

          List docDetailList = new ArrayList();
          log.debug("rowNU:>>>> " + j + " out of " +
                    sheet.getLastRowNum());
          ListDmsDocumentForm searchObject = new ListDmsDocumentForm();
          row = sheet.getRow( (short) j);
          log.debug("row = " + row.toString());

          //if empty row then move to the other row - begin
          boolean emptyRow = true;
          for (int k = 1; k <= row.getLastCellNum(); k++) {
            tmpCell = row.getCell( (short) k);
            if ( (tmpCell != null) && (tmpCell.getCellType() != HSSFCell.CELL_TYPE_BLANK)) {
              emptyRow = false;
            }
          }

          if (emptyRow) {
            continue;
          }
          //if empty row then move to the other row - end

          cell = row.getCell( (short) 0); //Full Text
          /*if (cell!=null)  {
                   cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                   searchObject.setFullText(cell.getStringCellValue().trim());
                   }*/

          cell = row.getCell( (short) 1); //Document Name
          if (cell != null) {
            if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
              value = TextUtility.formatInteger(new Double(cell.
                getNumericCellValue()).intValue());
            } else if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
              value = cell.getStringCellValue().trim();
            }
            searchObject.setDocumentName(value);
            searchObject.setDocumentNameExactMatch(false);
            log.debug("str value = " + value);
          }

          cell = row.getCell( (short) 2);
          if (cell != null) {
            if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
              value = TextUtility.formatInteger(new Double(cell.
                getNumericCellValue()).intValue());
            } else if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
              value = cell.getStringCellValue().trim();
            }

            searchObject.setEffectiveStartDate(TextUtility.formatTimestampToDBDate(TextUtility.parseTimestamp(value)));
            log.debug("str value = " + value);

          }

          cell = row.getCell( (short) 3);
          if (cell != null) {
            if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
              value = TextUtility.formatInteger(new Double(cell.
                getNumericCellValue()).intValue());
            } else if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
              value = cell.getStringCellValue().trim();
            }
            searchObject.setEffectiveEndDate(TextUtility.formatTimestampToDBDate(TextUtility.parseTimestamp(value)));
            log.debug("str value = " + value);
          }

          cell = row.getCell( (short) 4);
          if (cell != null) {
            if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
              value = TextUtility.formatInteger(new Double(cell.
                getNumericCellValue()).intValue());
            } else if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
              value = cell.getStringCellValue().trim();
            }
            searchObject.setReferenceNo(value);
            searchObject.setReferenceNoExactMatch(false);
            log.debug("str value = " + value);
          }

          cell = row.getCell( (short) 5);
          if (cell != null) {

            if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
              value = TextUtility.formatInteger(new Double(cell.
                getNumericCellValue()).intValue());
            } else if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
              value = cell.getStringCellValue().trim();
            }
            searchObject.setDescription(value);
            searchObject.setDescriptionExactMatch(false);
            log.debug("str value = " + value);
          }
          /*cell = row.getCell((short)4);
                   if (cell!=null){
                   cell.setCellType(HSSFCell.CELL_TYPE_STRING);
               searchObject.setUserDefinedID(cell.getStringCellValue().trim());
                   }*/

          //int rowCount = 6;

          //common profile read begin
          List defaultProfileSettingList = (List) request.getSession().getServletContext().getAttribute("DMS_DEF_PROFILE");
          int totalFieldCount = Integer.parseInt(com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.DMS_DEFAULT_PROFILE_FIELD_COUNT));
          //int rowCount = 6+totalFieldCount;
          int rowCount = 6;
          int totalFieldCountWithDate = 0;
          for (int i = 0; i < totalFieldCount; i++) {
            DmsDefaultProfileSetting setting = ( (DmsDefaultProfileSetting) defaultProfileSettingList.get(i));
            if (!DmsDefaultProfileSetting.FIELD_TYPE_DATE.equals(setting.getFieldType())) {
              rowCount++;
              totalFieldCountWithDate++;
            } else {
              rowCount = rowCount + 2;
              totalFieldCountWithDate = totalFieldCountWithDate + 2;
            }

          }

          int fieldCounter = 0;

          if (totalFieldCount > 0) {
            for (int i = 0; i < totalFieldCountWithDate; i++) {
              if (fieldCounter < totalFieldCount) {

                DmsDefaultProfileSetting setting = ( (DmsDefaultProfileSetting) defaultProfileSettingList.get(fieldCounter));
                cell = row.getCell( (short) (6 + i));
                if ( (cell != null) && (cell.getCellType() != HSSFCell.CELL_TYPE_BLANK)) {
                  if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
                    value = TextUtility.formatInteger(new Double(cell.
                      getNumericCellValue()).intValue());
                  } else if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
                    value = cell.getStringCellValue().trim();
                  }
                  if (fieldCounter == 0) {
                    if (!DmsDefaultProfileSetting.FIELD_TYPE_DATE.equals(setting.getFieldType())) {

                      searchObject.setUserDef1(value);
                      searchObject.setUserDef1ExactMatch(false);
                      log.debug("str value = " + value);
                    } else {
                      searchObject.setUserDef1(value);
                      searchObject.setUserDef1ExactMatch(false);
                      HSSFCell cellToDate = row.getCell( (short) (6 + i + 1));
                      if (cellToDate != null) {
                        searchObject.setUserDef1To(cellToDate.getStringCellValue().trim());
                      }
                      searchObject.setUserDef1DataType(DmsDefaultProfileSetting.FIELD_TYPE_DATE);
                      i++;
                    }
                  } else if (fieldCounter == 1) {
                    if (!DmsDefaultProfileSetting.FIELD_TYPE_DATE.equals(setting.getFieldType())) {
                      searchObject.setUserDef2(value);
                      searchObject.setUserDef2ExactMatch(false);
                      log.debug("str value = " + value);
                    } else {
                      searchObject.setUserDef2(value);
                      searchObject.setUserDef2ExactMatch(false);
                      HSSFCell cellToDate = row.getCell( (short) (6 + i + 1));

                      if (cellToDate != null) {

                        searchObject.setUserDef2To(cellToDate.getStringCellValue().trim());
                      }
                      searchObject.setUserDef2DataType(DmsDefaultProfileSetting.FIELD_TYPE_DATE);
                      i++;
                    }
                  } else if (fieldCounter == 2) {
                    if (!DmsDefaultProfileSetting.FIELD_TYPE_DATE.equals(setting.getFieldType())) {

                      searchObject.setUserDef3(value);
                      searchObject.setUserDef3ExactMatch(false);
                      log.debug("str value = " + value);
                    } else {
                      searchObject.setUserDef3(value);
                      searchObject.setUserDef3ExactMatch(false);
                      HSSFCell cellToDate = row.getCell( (short) (6 + i + 1));
                      if (cellToDate != null) {
                        searchObject.setUserDef3To(cellToDate.getStringCellValue().trim());
                      }
                      searchObject.setUserDef3DataType(DmsDefaultProfileSetting.FIELD_TYPE_DATE);
                      i++;
                    }

                  } else if (fieldCounter == 3) {
                    if (!DmsDefaultProfileSetting.FIELD_TYPE_DATE.equals(setting.getFieldType())) {

                      searchObject.setUserDef4(value);
                      searchObject.setUserDef4ExactMatch(false);
                      log.debug("str value = " + value);
                    } else {
                      searchObject.setUserDef4(value);
                      searchObject.setUserDef4ExactMatch(false);
                      HSSFCell cellToDate = row.getCell( (short) (6 + i + 1));
                      if (cellToDate != null) {
                        searchObject.setUserDef4To(cellToDate.getStringCellValue().trim());
                      }
                      searchObject.setUserDef4DataType(DmsDefaultProfileSetting.FIELD_TYPE_DATE);
                      i++;
                    }

                  } else if (fieldCounter == 4) {
                    if (!DmsDefaultProfileSetting.FIELD_TYPE_DATE.equals(setting.getFieldType())) {
                      searchObject.setUserDef5(value);
                      searchObject.setUserDef5ExactMatch(false);
                      log.debug("str value = " + value);
                    } else {
                      searchObject.setUserDef5(value);
                      searchObject.setUserDef5ExactMatch(false);
                      HSSFCell cellToDate = row.getCell( (short) (6 + i + 1));
                      if (cellToDate != null) {
                        searchObject.setUserDef5To(cellToDate.getStringCellValue().trim());
                      }
                      searchObject.setUserDef5DataType(DmsDefaultProfileSetting.FIELD_TYPE_DATE);
                      i++;
                    }
                  } else if (fieldCounter == 5) {
                    if (!DmsDefaultProfileSetting.FIELD_TYPE_DATE.equals(setting.getFieldType())) {
                      searchObject.setUserDef6(value);
                      searchObject.setUserDef6ExactMatch(false);
                      log.debug("str value = " + value);
                    } else {
                      searchObject.setUserDef6(value);
                      searchObject.setUserDef6ExactMatch(false);
                      HSSFCell cellToDate = row.getCell( (short) (6 + i + 1));
                      if (cellToDate != null) {
                        searchObject.setUserDef6To(cellToDate.getStringCellValue().trim());
                      }
                      searchObject.setUserDef6DataType(DmsDefaultProfileSetting.FIELD_TYPE_DATE);
                      i++;
                    }
                  } else if (fieldCounter == 6) {
                    if (!DmsDefaultProfileSetting.FIELD_TYPE_DATE.equals(setting.getFieldType())) {
                      searchObject.setUserDef7(value);
                      searchObject.setUserDef7ExactMatch(false);
                      log.debug("str value = " + value);
                    } else {
                      searchObject.setUserDef7(value);
                      searchObject.setUserDef7ExactMatch(false);
                      HSSFCell cellToDate = row.getCell( (short) (6 + i + 1));
                      if (cellToDate != null) {
                        searchObject.setUserDef7To(cellToDate.getStringCellValue().trim());
                      }
                      searchObject.setUserDef7DataType(DmsDefaultProfileSetting.FIELD_TYPE_DATE);
                      i++;
                    }
                  } else if (fieldCounter == 7) {
                    if (!DmsDefaultProfileSetting.FIELD_TYPE_DATE.equals(setting.getFieldType())) {
                      searchObject.setUserDef8(value);
                      searchObject.setUserDef8ExactMatch(false);
                      log.debug("str value = " + value);
                    } else {
                      searchObject.setUserDef8(value);
                      searchObject.setUserDef8ExactMatch(false);
                      HSSFCell cellToDate = row.getCell( (short) (6 + i + 1));
                      if (cellToDate != null) {
                        searchObject.setUserDef8To(cellToDate.getStringCellValue().trim());
                      }
                      searchObject.setUserDef8DataType(DmsDefaultProfileSetting.FIELD_TYPE_DATE);
                      i++;
                    }
                  } else if (fieldCounter == 8) {
                    if (!DmsDefaultProfileSetting.FIELD_TYPE_DATE.equals(setting.getFieldType())) {
                      searchObject.setUserDef9(value);
                      searchObject.setUserDef9ExactMatch(false);
                      log.debug("str value = " + value);
                    } else {
                      searchObject.setUserDef9(value);
                      searchObject.setUserDef9ExactMatch(false);
                      HSSFCell cellToDate = row.getCell( (short) (6 + i + 1));
                      if (cellToDate != null) {
                        searchObject.setUserDef9To(cellToDate.getStringCellValue().trim());

                      }
                      searchObject.setUserDef9DataType(DmsDefaultProfileSetting.FIELD_TYPE_DATE);
                      i++;
                    }
                  } else if (fieldCounter == 9) {
                    if (!DmsDefaultProfileSetting.FIELD_TYPE_DATE.equals(setting.getFieldType())) {
                      searchObject.setUserDef10(value);
                      searchObject.setUserDef10ExactMatch(false);
                      log.debug("str value = " + value);
                    } else {
                      searchObject.setUserDef10(value);
                      searchObject.setUserDef10ExactMatch(false);

                      HSSFCell cellToDate = row.getCell( (short) (6 + i + 1));
                      if (cellToDate != null) {
                        searchObject.setUserDef10To(cellToDate.getStringCellValue().trim());
                      }
                      searchObject.setUserDef10DataType(DmsDefaultProfileSetting.FIELD_TYPE_DATE);
                      i++;
                    }
                  }
                  //end of null cell
                } else {
                  if (DmsDefaultProfileSetting.FIELD_TYPE_DATE.equals(setting.getFieldType())) {
                    HSSFCell cellToDate = row.getCell( (short) (6 + i + 1));
                    if (cellToDate != null) {
                      Method setUserDefTo = searchObject.getClass().getMethod("setUserDef" + (fieldCounter + 1) + "To", new Class[] {String.class});
                      Method setUserDefDataType = searchObject.getClass().getMethod("setUserDef" + (fieldCounter + 1) + "DataType", new Class[] {String.class});
                      String userDefTo[] = new String[1];
                      String userDefDataType[] = new String[1];
                      userDefTo[0] = cellToDate.getStringCellValue();
                      userDefDataType[0] = DmsDefaultProfileSetting.FIELD_TYPE_DATE;
                      setUserDefTo.invoke(searchObject, userDefTo);
                      setUserDefDataType.invoke(searchObject, userDefDataType);
                      //searchObject.setUserDef10To.setToDateValue(cellToDate.getStringCellValue());
                      //searchObject.setUserDef10DataType(DmsDefaultProfileSetting.FIELD_TYPE_DATE);
                    }

                    i++;
                  }
                }
              } //end if fieldCounter < totalFieldCount
              fieldCounter++;
            } //end for
          } //end out if

          /*
                     if(totalFieldCount>0){
            for(int i=0;i<totalFieldCount;i++){
              cell = row.getCell( (short)(6+i) );
              if (cell != null) {
                if(cell.getCellType()==HSSFCell.CELL_TYPE_NUMERIC){
                  value = TextUtility.formatInteger(new Double(cell.
                  getNumericCellValue()).intValue());
                }else if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
                  value = cell.getStringCellValue().trim();
                }
                if(i==0){
                  searchObject.setUserDef1(value);
                  searchObject.setUserDef1ExactMatch(false);
                  log.debug("str value = " + value);
                }else if(i==1){
                  searchObject.setUserDef2(value);
                  searchObject.setUserDef2ExactMatch(false);
                  log.debug("str value = " + value);
                }else if(i==2){
                  searchObject.setUserDef3(value);
                  searchObject.setUserDef3ExactMatch(false);
                  log.debug("str value = " + value);
                }else if(i==3){
                  searchObject.setUserDef4(value);
                  searchObject.setUserDef4ExactMatch(false);
                  log.debug("str value = " + value);
                }else if(i==4){
                  searchObject.setUserDef5(value);
                  searchObject.setUserDef5ExactMatch(false);
                  log.debug("str value = " + value);
                }else if(i==5){
                  searchObject.setUserDef6(value);
                  searchObject.setUserDef6ExactMatch(false);
                  log.debug("str value = " + value);
                }else if(i==6){
                  searchObject.setUserDef7(value);
                  searchObject.setUserDef7ExactMatch(false);
                  log.debug("str value = " + value);
                }else if(i==7){
                  searchObject.setUserDef8(value);
                  searchObject.setUserDef8ExactMatch(false);
                  log.debug("str value = " + value);
                }else if(i==8){
                  searchObject.setUserDef9(value);
                  searchObject.setUserDef9ExactMatch(false);
                  log.debug("str value = " + value);
                }else if(i==9){
                  searchObject.setUserDef9(value);
                  searchObject.setUserDef9ExactMatch(false);
                  log.debug("str value = " + value);
                }
              }
            }//end for
                     }//end out if
                     //common profile read end
           */

          if (row.getLastCellNum() >= rowCount) {
            DmsDocumentDetail oldDocDetail = null;

            for (int i = rowCount; i < row.getLastCellNum(); i++) {

              DmsDocumentDetail dmsDetail = null;
              dmsDetail = new DmsDocumentDetail();
              dmsDetail.setUserDefinedFieldID(TextUtility.parseIntegerObj(
                criteria[i].substring(0, criteria[i].indexOf("_"))));
              dmsDetail.setUserDefinedFieldDetailID(TextUtility.parseIntegerObj(
                criteria[i].substring(criteria[i].indexOf("_") + 1,
                                      criteria[i].length())));

              SysUserDefinedIndexDetailDAObject udfDetailDAO = new
                SysUserDefinedIndexDetailDAObject(sessionContainer, conn);
              SysUserDefinedIndexDetail udfDetail = (SysUserDefinedIndexDetail)
                udfDetailDAO.getObjectByID(dmsDetail.
                                           getUserDefinedFieldDetailID());
              searchObject.setUserDefinedFieldID(TextUtility.formatIntegerObj(udfDetail.getUserDefinedID()));

              cell = row.getCell( (short) i);

              if (cell != null) { //contain some value
                int cellType = cell.getCellType();

                if (cellType == HSSFCell.CELL_TYPE_BLANK) { //case of blank
                  //log.debug("blank in row:  " + j + " cell: " + i);
                  dmsDetail.setFieldValue("");

                  if (i < criteria.length - 1 &&
                      criteria[i].equals(criteria[i + 1])) {
                    i++;
                  }

                } else if (SysUserDefinedIndexDetail.STRING_FIELD.equals(udfDetail.getFieldType()) || SysUserDefinedIndexDetail.FIELD_TYPE_SELECT_DATABASE.equals(udfDetail.getFieldType())) { //case of string value
                  if (cellType == HSSFCell.CELL_TYPE_STRING) {
                    //log.debug(" String row:  " + j + " String cell: " + i +
                    //" : " + cell.getStringCellValue().trim());
                    dmsDetail.setFieldValue(cell.getStringCellValue().trim());
                  }

                } else if (SysUserDefinedIndexDetail.DATE_FIELD.equals(udfDetail.getFieldType())) { //case of date value
                  //log.debug("date criteria size: " + criteria.length +
                  // " " + i);

                  if (i < criteria.length - 1 &&
                      criteria[i].equals(criteria[i + 1])) {
                    //log.debug("row:  " + j + " cell: " + i +
                    //" From Date: " + cell.getStringCellValue());

                    //dmsDetail.setDateValue(TextUtility.parseTimestamp(TextUtility.formatDate(cell.getStringCellValue(), SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATE_FORMAT))));
                    dmsDetail.setDateValue(TextUtility.parseTimestamp(cell.
                      getStringCellValue()));
                    HSSFCell cellToDate = row.getCell( (short) (i + 1));
                    if (cellToDate != null) {
                      //dmsDetail.setToDateValue(TextUtility.parseTimestamp(TextUtility.formatDate(cellToDate.getDateCellValue(), SystemParameterFactory.getSystemParameter(SystemParameterConstant.DATE_FORMAT))));
                      dmsDetail.setToDateValue(TextUtility.parseTimestamp(
                        cellToDate.getStringCellValue()));
                    }
                    i++;

                  }
                } else { //numeric value
                  if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {
                    //log.debug("criteria size: " + criteria.length + " " + i);
                    Double dValue = new Double(cell.getNumericCellValue());
                    //log.debug("row:  " + j + " cell: " + i + "  Other Number: " + dValue);
                    dmsDetail.setNumericValue(dValue);
                  }

                }
              } else { //end of not null cell
                //log.debug("blank in row:  " + j + " cell: " + i);
                if (!SysUserDefinedIndexDetail.DATE_FIELD.equals(udfDetail.getFieldType())) {
                  dmsDetail.setFieldValue("");
                  if (i < criteria.length - 1 &&
                      criteria[i].equals(criteria[i + 1])) {
                    i++;
                  }
                } else {
                  if (i < criteria.length - 1 &&
                      criteria[i].equals(criteria[i + 1])) {

                    HSSFCell cellToDate = row.getCell( (short) (i + 1));
                    if (cellToDate != null) {
                      dmsDetail.setToDateValue(TextUtility.parseTimestamp(
                        cellToDate.getStringCellValue()));
                    }
                    i++;

                  }

                }

              } //end else
//            }

              //log.debug("getToDateValue: " + dmsDetail.getToDateValue());
              dmsDetail.setFieldType(udfDetail.getFieldType());
              docDetailList.add(dmsDetail);
            }
          }
          //log.debug("size ---> " + j + " "+  docDetailList.size());
          if (docDetailList != null && docDetailList.size() > 0) {
            searchObject.setDocumentDetails(docDetailList);
          }

          searchObject.setRootID(rootID);

          //searchObject.setNecessary(true);
          searchObjectList.add( searchObject);
        } //end for sheet
      } // end if
    } catch (Exception e) {
      log.debug("error in reading excel: " + e.getMessage());
      throw new ExcelUnReadableException(DmsErrorConstant.READ_EXCEL_FAILED);
    }
    return searchObjectList;
  }

  /**
   * exporting excel file for bulk serach
   *
   */
  public void exportExcel(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    log.debug("export the udf search criteria");
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);

    RootRetrievalManager rootRetrievalManager = new RootRetrievalManager(sessionContainer, conn);
    ListDmsDocumentForm documentForm = (ListDmsDocumentForm) form;
    String sUDFID = null;
    Integer nUDFID = null;
    if (documentForm.getBulkSearchExportUserDefinedFieldID() != null) {
      sUDFID = documentForm.getBulkSearchExportUserDefinedFieldID();
    }
    String filename = "";
    String sUDFType = "General";
    List udfDetailList = new ArrayList();
    try {
      if (!Utility.isEmpty(sUDFID)) {
        nUDFID = new Integer(sUDFID);
        SysUserDefinedIndexDAObject udfDAO = new SysUserDefinedIndexDAObject(sessionContainer, conn);
        SysUserDefinedIndexDetailDAObject udfDetailDAO = new SysUserDefinedIndexDetailDAObject(sessionContainer, conn);
        SysUserDefinedIndex udf = (SysUserDefinedIndex) udfDAO.getObjectByID(nUDFID);
        sUDFType = udf.getUserDefinedType();
        udfDetailList = udfDetailDAO.getListBySysUserDefinedIndexID(nUDFID);
      }
      /* creating excel file */
      HSSFWorkbook wb = new HSSFWorkbook();
      
      //replace invalid character with space. (lee add 06/12/20 EIP-1160)
      sUDFType = TextUtility.replaceInvalidChar(sUDFType, " ");
      
      HSSFSheet sheet = wb.createSheet(sUDFType);
      sheet.setDefaultColumnWidth( (short) 18);
      short rowNum = 0;
      HSSFRow row = sheet.createRow(rowNum);

      // adding search criteria
      //createCell(wb, row, (short) 0, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.full_text"));
      createCell(wb, row, (short) 1, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.name_label_D"));
      createCell(wb, row, (short) 2,
                 MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.effective_start_date") + "(" +
                 (com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.DATE_FORMAT)) + ")");
      createCell(wb, row, (short) 3,
                 MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.effective_end_date") + "(" +
                 (com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.DATE_FORMAT)) + ")");
      createCell(wb, row, (short) 4, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.reference_no"));
      createCell(wb, row, (short) 5, MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.description"));
      int column = 6;

      //Common profiles
      List defaultProfileSettingList = (List) request.getSession().getServletContext().getAttribute("DMS_DEF_PROFILE");
      int totalFieldCount = Integer.parseInt(com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.DMS_DEFAULT_PROFILE_FIELD_COUNT));

      if (!Utility.isEmpty(defaultProfileSettingList)) {
        for (int i = 0; i < totalFieldCount; i++) {
          DmsDefaultProfileSetting setting = ( (DmsDefaultProfileSetting) defaultProfileSettingList.get(i));
          if (!DmsDefaultProfileSetting.FIELD_TYPE_DATE.equals(setting.getFieldType())) {
            createCell(wb, row, (short) column++, setting.getFieldName());
          } else {
            createCell(wb, row, (short) column++,
                       setting.getFieldName() + "(" + (com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.DATE_FORMAT)) + ")");
            createCell(wb, row, (short) column++,
                       setting.getFieldName() + " To " + "(" + (com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.DATE_FORMAT)) + ")");
          }

        }
      }

      //UDF Profiles
      SysUserDefinedIndexDetail udfDetail = null;
      for (int i = 0; i < udfDetailList.size(); i++) {
        udfDetail = (SysUserDefinedIndexDetail) udfDetailList.get(i);

        if (SysUserDefinedIndexDetail.DATE_FIELD.equals(udfDetail.getFieldType())) {
          createCell(wb, row, (short) column++,
                     udfDetail.getFieldName() + "(" + (com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.DATE_FORMAT)) + ") " +
                     "[" + nUDFID + "_" + udfDetail.getID() + "]");
          createCell(wb, row, (short) column++,
                     udfDetail.getFieldName() + " To " + "(" + (com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.DATE_FORMAT)) + ") " +
                     "[" + nUDFID + "_" + udfDetail.getID() + "]");
        } else {
          createCell(wb, row, (short) column++, udfDetail.getFieldName() + "[" + nUDFID + "_" + udfDetail.getID() + "]");
        }
      }
      DmsLocMaster locMaster = rootRetrievalManager.getLocMasterOfPersonalRootByOwnerID(sessionContainer.getUserRecordID());
      String locMasterPath = locMaster.getLocPath();
      filename = locMasterPath + "/search" + sUDFID + ".xls";
      log.debug("locMasterPath = " + locMasterPath);
      FileOutputStream fileOut = new FileOutputStream(filename);
      wb.write(fileOut);
      fileOut.close();
      request.setAttribute("filename", filename);
      request.getSession().setAttribute("exlExportFileName",filename);//barbin.tao 2006-4-19
      //close the excel file

      //reset the arraylist
      request.setAttribute(this.m_sListName, new ArrayList());
      sessionContainer = null;
      rootRetrievalManager.release();
    } catch (ApplicationException appEx) {
      throw appEx;
    } catch (Exception e) {
      log.error(e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    } finally {
      conn = null;
    }
  }

  /**
   * Bulk repalce for document details by searching criteria
   *
   */
  public List replaceCriteria(ActionMapping mapping, AbstractSearchForm form,
                              HttpServletRequest request,
                              HttpServletResponse response) throws
    ApplicationException {
    List docList = new ArrayList();
    return docList;
  }

  /**
   * Creates a cell and aligns it a certain way.
   *
   * @param wb        the workbook
   * @param row       the row to create the cell in
   * @param column    the column number to create the cell in
   * @param align     the alignment for the cell.
   */
  private static void createCell(HSSFWorkbook wb, HSSFRow row, short column,
                                 String value) {
    HSSFCell cell = row.createCell(column);
    cell.setEncoding(cell.ENCODING_UTF_16);
    cell.setCellValue(value);
    //HSSFCellStyle cellStyle = wb.createCellStyle();
    //cellStyle.setAlignment(align);
    //cell.setCellStyle(cellStyle);
  }

  public void refreshFormData(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    try {
      ListDmsDocumentForm documentForm = (ListDmsDocumentForm) form;
      List udfDetailList = docRetrievalManager.getUDFDetailList(TextUtility.parseIntegerObj(documentForm.getUserDefinedFieldID()));
      documentForm.setUdfDetailList(udfDetailList);
      documentForm.setDocDetailsSize(TextUtility.formatInteger(udfDetailList.size()));
      //documentForm.setSearchFolder(null);
      //documentForm.setBulkSearchExportUserDefinedFieldID("");
      log.debug("udf detail list size = " + udfDetailList.size());

      List resultList = request.getAttribute(this.m_sListName) == null ?
        new ArrayList() : (List) request.getAttribute(this.m_sListName);

      if (DmsOperationConstant.SEARCH_RESULT_RESET.equals(documentForm.getAdvSearchOpt())) {
        request.setAttribute(this.m_sListName, resultList);
        request.getSession().setAttribute(this.m_sListName, null);
        request.getSession().setAttribute("outerCriteriaValue", null);
      } else if (Utility.isEmpty(resultList)) {
        resultList = request.getAttribute(this.m_sListName) == null ?
          new ArrayList() : (List) request.getAttribute(this.m_sListName);
      }
      String rootDocumentID = (String)request.getSession().getAttribute("searchFolderIds");
      if( !Utility.isEmpty(rootDocumentID)) {
        String[] ids = new String[] {rootDocumentID};
        documentForm.setSearchFolder(ids);
      }else{
        RootRetrievalManager rootRetrevalManager = new RootRetrievalManager(sessionContainer, conn);
        List rootList = rootRetrevalManager.getAllAccessibleRootsList();
        String[] ids = new String[rootList.size()];
        for(int j=0; j<rootList.size(); j++){
          DmsRoot dmsRoot = (DmsRoot)rootList.get(j); 
          ids[j]= dmsRoot.getID().toString();
        }
        documentForm.setSearchFolder(ids);
      }
      request.setAttribute(this.m_sListName, resultList);
      sessionContainer = null;
      docRetrievalManager.release();
    } catch (ApplicationException appEx) {
      throw appEx;
    } catch (Exception e) {
      log.error(e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    } finally {
      conn = null;
    }

  }

  /**
   *  Method deleteListData() - delete the item(s) from listing page
   *
   *  @param      mapping               ActionMapping from struts
   *  @param      form                  ActionForm from struts
   *  @param      request               HttpServletReuqest
   *  @param      respond               HttpServletRespond
   *  @return     void
   *  @throws     ApplicationException  Throws ApplicationException the deleteion failed
   *  @deprecated This method had deperecated.
   */
  
  
  public void deleteListData(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    DocumentOperationManager docOperationManager = new DocumentOperationManager(sessionContainer, conn);
    ListDmsDocumentForm listForm=(ListDmsDocumentForm)form;
    
    DmsDocumentDAObject dmsDocmentDAO = new DmsDocumentDAObject(sessionContainer, conn);
    DmsDocument targetDoc = null;
    String itstatus = "";

    try {
      String[] selectedID = form.getBasicSelectedID();
      if(Utility.isEmpty(selectedID)){
        selectedID=TextUtility.splitString(listForm.getDeleteSelectID(),",");
        form.setBasicSelectedID(selectedID);
      }
      for (int i = 0; i < selectedID.length; i++) {
      	targetDoc = (DmsDocument)dmsDocmentDAO.getObjectByID(TextUtility.parseIntegerObj(selectedID[i]));
        itstatus = targetDoc.getItemStatus();

        if (!Utility.isEmpty(selectedID[i])) {
          PermissionManager permManager = sessionContainer.getPermissionManager();
          DmsDocument document = docRetrievalManager.getDocument(TextUtility.parseIntegerObj(selectedID[i]));
          if (DmsDocument.DOCUMENT_TYPE.equals(document.getDocumentType())) {
          	if ("X".equals(itstatus)) {
                throw new ApplicationException(ErrorConstant.DMS_MESSAGE_CHECKOUT_NOT_DELETE);
          	} else if(!permManager.hasAccessRight(conn,"D",document.getID(),"D")){
          		throw new ApplicationException(DmsErrorConstant.DMS_MESSAGE_PERMISSION_NOT_DELETE);
          	}
          	else{
            docOperationManager.deleteDocument(document);
          	}
          } else {
          	if ("X".equals(itstatus)) {
                throw new ApplicationException(ErrorConstant.DMS_MESSAGE_CHECKOUT_NOT_DELETE);
          	}else{
              docOperationManager.deleteDocument(document);
          	}
          }
        }
      }
      conn.commit() ;
    } catch (ApplicationException appEx) {
      throw appEx;
    } catch (Exception e) {
      log.error(e, e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    } finally {
      conn = null;
    }
  }

  /* Jicle.Wang 6143 2006/08/25 Start */
  /**
   *  Method deleteListData2() - delete the item(s) and relation_document(s) from listing page
   *
   *  @param      mapping               ActionMapping from struts
   *  @param      form                  ActionForm from struts
   *  @param      request               HttpServletReuqest
   *  @param      respond               HttpServletRespond
   *  @return     void
   *  @throws     ApplicationException  Throws ApplicationException the deleteion failed
   */
  public void deleteListData2(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
	    SessionContainer sessionContainer = this.getSessionContainer(request);
	    Connection conn = this.getConnection(request);
	    DocumentValidateManager docValidateManager = new DocumentValidateManager(sessionContainer, conn);
	    DocumentOperationManager docOperationManager = new DocumentOperationManager(sessionContainer, conn);
	    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
	    DmsDocumentDAObject dmsDocumentDAO = new DmsDocumentDAObject(sessionContainer, conn);
	    ApplicationContainer container = (ApplicationContainer)request.getSession().getServletContext().getAttribute(GlobalConstant.APPLICATION_CONTAINER_KEY);
	    
	    String[] selectedID = form.getBasicSelectedID();
	    boolean isIgnoreDeleteShortcut = ((ListDmsDocumentForm)form).isIgnoreDeleteShortcut();
	    //step 1: loop and validate tree node, add id to lstIdHasRight/lstIdMisRight/lstIdBeLocked
	    for (int n=0; n<selectedID.length; n++) {
	      Integer srcDocumentId = TextUtility.parseIntegerObj(selectedID[n]);
	      DmsDocument sourceDocument = (DmsDocument)dmsDocumentDAO.getObjectByID(srcDocumentId);
	      DmsValidation validation = docValidateManager.validateDeleteAction(sourceDocument, isIgnoreDeleteShortcut);
	      
	      //step 2: begin delete documents
	      String cacheKey = "D"+sessionContainer.getSessionID()+""+System.currentTimeMillis();
	      try {
	        List deleteDocumentIds = validation.getLstIdAccept();
	        //step 2.1: check and lock operation id to application cache
	        boolean success = container.checkAndLockDocumentOperationID(cacheKey, deleteDocumentIds, "ACDIMU");
	        if (!success) {
	          this.addError(request, "errors.dms.fail_to_delete", docRetrievalManager.getLocationPath(srcDocumentId));
	          this.addError(request, "errors.dms.cannot_edit_now");
	        }else {
	          //step 2.2: delete documents
	          docOperationManager.deleteDocument(sourceDocument, validation);
	        
	          //step 2.3: message throws
	          List lstIdHasRight = validation.getLstIdAccept();
	          List lstIdMisRight = validation.getLstIdReject();
	          List lstIdBeLocked = validation.getLstIdlocked();
	          List lstIdBeDeleted = validation.getLstIdDeleted();
	          List lstIdBeArchived = validation.getLstIdArchived();
	          List lstIdRelatedShortcut = validation.getLstIdHaveRelationship();
	          String locationPath = docRetrievalManager.getLocationPath(srcDocumentId);
	          if (validation.isSuccess()) {
	            this.addMessage(request, "dms.message.document_deleted_success", locationPath, String.valueOf(lstIdHasRight.size()));
	          }else {
	            this.addError(request, "errors.dms.fail_to_delete", locationPath);
	            for (int i=0; i<lstIdMisRight.size(); i++) {
	              this.addError(request,"errors.dms.no_permission",docRetrievalManager.getLocationPath((Integer)lstIdMisRight.get(i)));                            
	            }
	            for (int i=0; i<lstIdBeLocked.size(); i++) {
	              this.addError(request,"errors.dms.been_checkout",docRetrievalManager.getLocationPath((Integer)lstIdBeLocked.get(i)));                            
	            }
	            for (int i=0; i<lstIdBeDeleted.size(); i++) {
	              this.addError(request,"errors.dms.been_deleted",docRetrievalManager.getLocationPath((Integer)lstIdBeDeleted.get(i)));                            
	            }
	            for (int i=0; i<lstIdBeArchived.size(); i++) {
	              this.addError(request,"errors.dms.been_archived",docRetrievalManager.getLocationPath((Integer)lstIdBeArchived.get(i)));                            
	            }
	            for (int i=0; i<lstIdRelatedShortcut.size(); i++) {
	              this.addError(request,"errors.dms.has_relationship",docRetrievalManager.getLocationPath((Integer)lstIdRelatedShortcut.get(i)));                            
	            }
              }
	          
	          //step 2.4: delete from clipboard if it present
	          List clipboardList = (List)request.getSession().getAttribute("DMS_CLIPBOARD");
	          if (clipboardList!=null && !clipboardList.isEmpty()) {
	            for (int i=0; i<clipboardList.size(); i++) {
	              if(deleteDocumentIds.contains(clipboardList.get(i))) {
	                clipboardList.remove(i--);
	              }
	            }
	          }
	        }
	      }catch (ApplicationException ex) {
	        throw ex;
	      }catch (Exception ex) {
	        throw new ApplicationException(ex);
	      }finally {
	        container.unlockDmsDocumentOperationID(cacheKey);
	      }
	    }
	    conn = null;
	    sessionContainer = null;
	    container = null;
	    docValidateManager.release();
	    docOperationManager.release();
	    docRetrievalManager.release();
	  } 
  /* Jicle.Wang 6143 2006/08/25 End   */
  
  public boolean checkIsTiff(Integer documentID, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    DocumentOperationManager docOperationManager = new DocumentOperationManager(sessionContainer, conn);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);

    try {
      List list = docOperationManager.getSubDocumentByParentID(documentID);
      DmsDocument document = docRetrievalManager.getDocument(documentID);
      list.add(document);
      for (int i = 0; i < list.size(); i++) {
        DmsDocument dmsDocument = (DmsDocument) list.get(i);
        String name = dmsDocument.getDocumentName();
        if (! ("TIF".equals(TextUtility.getExtension(name))) && ! ("TIFF".equals(TextUtility.getExtension(name)))) {
          return false;
        }
      }
      return true;
    } catch (ApplicationException appEx) {
      throw appEx;
    } finally {
      sessionContainer = null;
      conn = null;
      docOperationManager.release();
      docRetrievalManager.release();
    }
  }


  public void selectQueryRecord(ActionMapping mapping, ActionForm form,HttpServletRequest request,HttpServletResponse response) throws ApplicationException{
    Integer queryID=TextUtility.parseIntegerObj(request.getParameter("queryID"));
    DmsQueryRecordDAObject dmsQueryRecordDAO=new DmsQueryRecordDAObject(this.getSessionContainer(request),this.getConnection(request));
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(this.getSessionContainer(request),this.getConnection(request));
    ListDmsDocumentForm listForm=(ListDmsDocumentForm)form;
    try{
      DmsQueryRecord dmsQueryRecord=(DmsQueryRecord)dmsQueryRecordDAO.getObjectByID(queryID);
      StringBuffer writerBean=(StringBuffer)dmsQueryRecord.getXmlQuery();
      ParseQueryRecordXML queryRecordXML=new ParseQueryRecordXML();
      queryRecordXML.getParseing(form,request,writerBean);
      if(!Utility.isEmpty(listForm.getUserDefinedFieldID())){
        List udfDetailList = docRetrievalManager.getUDFDetailList(TextUtility.parseIntegerObj(listForm.getUserDefinedFieldID()));
        listForm.setUdfDetailList(udfDetailList);
        /*
         * joan.xiong add code for bug EIP-335 by 2006/09/22
         * When used profile search,the result can't update without reset.
         * The solution is reset the DocumentDetailList.
         */
        String[] fieldID = (String[])request.getAttribute("proFieldID");
        String[] fromValue = (String[])request.getAttribute("proFromValue");
        String[] toValue = (String[])request.getAttribute("proToValue");
        String[] fieldType = (String[])request.getAttribute("proFieldType");
        String[] fieldOption = (String[])request.getAttribute("proFieldOption");
        String[] fieldExMatch = (String[])request.getAttribute("proFieldExMatch");
        List documentDetailList = listForm.getDocumentDetails();
        List newDocDetail = new ArrayList();
        for(int i=0;i<fieldExMatch.length;i++){
        	DmsDocumentDetail dmsDocumentDetail = new DmsDocumentDetail();
        		dmsDocumentDetail.setUserDefinedFieldDetailID(TextUtility.parseIntegerObj(fieldID[i]));
        		dmsDocumentDetail.setFieldType(fieldType[i]);
        		dmsDocumentDetail.setSearchOption(fieldOption[i]);
        		dmsDocumentDetail.setExactMatch(TextUtility.parseBoolean(fieldExMatch[i]));
        		dmsDocumentDetail.setRecordStatus("A");
        		if(SysUserDefinedIndexDetail.DATE_FIELD.equals(fieldType[i])){
        			dmsDocumentDetail.setDateValue(TextUtility.parseDBDateTimeToTimeStamp(fromValue[i]));
        			dmsDocumentDetail.setToDateValue(TextUtility.parseDBDateTimeToTimeStamp(toValue[i]));
        		}else if(SysUserDefinedIndexDetail.NUMBER_FIELD.equals(fieldType[i])){
        			dmsDocumentDetail.setNumericValue(TextUtility.parseDoubleObj(fromValue[i]));
        			dmsDocumentDetail.setToNumericValue(TextUtility.parseDoubleObj(toValue[i]));
        		}else{
        			dmsDocumentDetail.setFieldValue(fromValue[i]);
        			dmsDocumentDetail.setToFieldValue(toValue[i]);
        		}
        	newDocDetail.add(dmsDocumentDetail);
        }
        listForm.setDocumentDetails(newDocDetail);
        /*
         * joan.xiong add code end
         */
      }
    }catch(Exception e){log.error(e, e);}
  }

  protected boolean hasSubDocument(DmsDocument dmsDocument,HttpServletRequest request) throws ApplicationException{
    DocumentOperationManager docOperationManager = new DocumentOperationManager(this.getSessionContainer(request), this.getConnection(request));
    List list= docOperationManager.getSubDocumentByParentID(dmsDocument.getID());
    if(list.size()>0){
      return true;
    }else{
      return false;
    }
  }

  public List searchRelationalWord(String keyword,HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
     SessionContainer sessionContainer = this.getSessionContainer(request);
     Connection conn = this.getConnection(request);
     List relationList = new ArrayList();
     List relationTestList = new ArrayList();
     String nKeyword="";
     String word="";
     try{
       DmsRelationalWordDAObject dmsRelationalWordDaobject = new DmsRelationalWordDAObject(sessionContainer, conn);
       if(keyword.startsWith("\"")){
          if(keyword.indexOf("||")>0){
            String []keyWord=TextUtility.splitString(keyword,"||");

            for(int i=0;i<keyWord.length;i++){
              if(!keyWord[i].equals("||")){
                word=keyWord[i];
                String testWord=word.substring(word.indexOf("\"")+1,word.lastIndexOf("\""));
                 List relationalWordList = dmsRelationalWordDaobject.getRelationalWordListByKeyWord(testWord);
                 for(int n=0;n<relationalWordList.size();n++){
                   DmsRelationalWord dmsRelationalWord = (DmsRelationalWord)relationalWordList.get(n);
                   String relationKeyWord = dmsRelationalWord.getWord();
                   testWord = testWord+" || " +"\""+TextUtility.convert(relationKeyWord) +"\""+" || " +"\""+relationKeyWord +"\"";
                 }
                 relationList.add(testWord);
               }
            }
          }else if(keyword.indexOf("&&")>0){
//            String []keyWord=TextUtility.splitString(keyword,"&&");
//            for(int i=0;i<keyWord.length;i++){
//               if(!keyWord[i].equals("&&")){
//                 word=keyWord[i];
//                 String testWord=word.substring(word.indexOf("\"")+1,word.lastIndexOf("\""));
//                 List relationalWordList = dmsRelationalWordDaobject.getRelationalWordListByKeyWord(testWord);
//                 for(int n=0;n<relationalWordList.size();n++){
//                   DmsRelationalWord dmsRelationalWord = (DmsRelationalWord)relationalWordList.get(n);
//                   String relationKeyWord = dmsRelationalWord.getWord();
//                   testWord = testWord+" || " +"\""+TextUtility.convert(relationKeyWord) +"\""+" || " +"\""+relationKeyWord +"\"";
//                 }
//                 relationList.add(testWord);
//                }
//
//            }
          }
        }else{
          if(keyword.indexOf("&&")>0){
//            String []keyWord=TextUtility.splitString(keyword,"&&");
//            String test="";
//            String keyWord1="";
//            for(int i=0;i<keyWord.length;i++){
//                word=keyWord[i];
//                String []testWord=TextUtility.splitString(word," ");
//                for(int d=0;d<testWord.length;d++){
//                  keyWord1=testWord[d];
//                  List relationalWordList = dmsRelationalWordDaobject.getRelationalWordListByKeyWord(testWord[d]);
//                  for(int n=0;n<relationalWordList.size();n++){
//                    DmsRelationalWord dmsRelationalWord = (DmsRelationalWord)relationalWordList.get(n);
//                    String relationKeyWord = dmsRelationalWord.getWord();
//                    keyWord1 = keyWord1+" || "+"\""+TextUtility.convert(relationKeyWord) +"\""+" || " +"\""+relationKeyWord +"\"";
//                  }
//                  test=test+"||"+"("+keyWord1+")";
//                }
//                String []test1=TextUtility.splitString(test.substring(2),"||()||");
//                String test2="";
//                for(int x=0;x<test1.length;x++){
//                   test2=test1[x];
//                }
//                relationList.add(test2);
//            }
          }else if(keyword.indexOf("||")>0){
             String []keyWord=TextUtility.splitString(keyword," ");
             for(int i=0;i<keyWord.length;i++){
               if(!keyWord[i].equals("||")){
                 word=keyWord[i];
                 List relationalWordList = dmsRelationalWordDaobject.getRelationalWordListByKeyWord(keyWord[i]);
                 for(int n=0;n<relationalWordList.size();n++){
                   DmsRelationalWord dmsRelationalWord = (DmsRelationalWord)relationalWordList.get(n);
                   String relationKeyWord = dmsRelationalWord.getWord();
                   word = word+" || " +"\""+TextUtility.convert(relationKeyWord) +"\""+" || " +"\""+relationKeyWord +"\"";
                 }
                relationList.add(word);
               }
             }
          }else{
             String []keyWord=TextUtility.splitString(keyword," ");
             for(int i=0;i<keyWord.length;i++){
                word=keyWord[i];
                List relationalWordList = dmsRelationalWordDaobject.getRelationalWordListByKeyWord(keyWord[i]);
                for(int n=0;n<relationalWordList.size();n++){
                  DmsRelationalWord dmsRelationalWord = (DmsRelationalWord)relationalWordList.get(n);
                  String relationKeyWord = dmsRelationalWord.getWord();
                  word = word+" || " +"\""+TextUtility.convert(relationKeyWord) +"\""+" || " +"\""+relationKeyWord +"\"";
                }
                relationList.add(word);
             }
             
             List relationalWordList = dmsRelationalWordDaobject.getRelationalWordListByKeyWord(keyword);
             for(int n=0;n<relationalWordList.size();n++){
               DmsRelationalWord dmsRelationalWord = (DmsRelationalWord)relationalWordList.get(n);
               String relationKeyWord = dmsRelationalWord.getWord();
               word = word+" || " +"\""+TextUtility.convert(relationKeyWord) +"\""+" || " +"\""+relationKeyWord +"\"";
             }
             relationList.add(word);             
          }
       }
     } catch (Exception e) {
       log.error(e, e);
     }finally {
        conn = null;
     }
     return relationList;
  }

  private void retreiveWF(HttpServletRequest request) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    // Retrive the workflow relationship.
    List listDoc = (List)request.getAttribute(this.m_sListName);
    List listWorkflowRelation = new ArrayList();
    com.dcivision.workflow.dao.MtmWorkflowProgressSystemObjectDAObject mtmWfProgressSysObjDAO = new com.dcivision.workflow.dao.
    MtmWorkflowProgressSystemObjectDAObject(this.getSessionContainer(request), conn);
    com.dcivision.workflow.dao.WorkflowRecordDAObject workflowRecordDAO = new com.dcivision.workflow.dao.WorkflowRecordDAObject(this.getSessionContainer(request), conn);
    for (int i = 0; i < listDoc.size(); i++) {
      List tmpList =new ArrayList();
      
      try {
        if (DmsDocument.DOCUMENT_LINK.equals(((DmsDocument)listDoc.get(i)).getDocumentType())) {
          if (!Utility.isEmpty(((DmsDocument)listDoc.get(i)).getID())) {
            DmsDocument targetDoc = docRetrievalManager.getRelationshipTargetDocument(((DmsDocument)listDoc.get(i)).getID(),((DmsDocument)listDoc.get(i)).getDocumentType());
            if (targetDoc!=null) {
              tmpList = mtmWfProgressSysObjDAO.getListByBeanClassNameObjectID(listDoc.get(i).getClass().getName(), targetDoc.getID());
            }
          }
        } else {
          tmpList = mtmWfProgressSysObjDAO.getListByBeanClassNameObjectID(listDoc.get(i).getClass().getName(), ( (DmsDocument)listDoc.get(i)).getID());
        }
        //List tmpList =  mtmWfProgressSysObjDAO.getListByBeanClassNameObjectID(listDoc.get(i).getClass().getName(), ( (DmsDocument)listDoc.get(i)).getID());
      }catch (Exception ex) {
        log.warn("Database has dity record."+ex, ex);
      }
      List tmpRow = new ArrayList();
      listWorkflowRelation.add(i, tmpRow);
      for (int j = 0; j < tmpList.size(); j++) {
        com.dcivision.workflow.bean.MtmWorkflowProgressSystemObject tmpObj = (com.dcivision.workflow.bean.MtmWorkflowProgressSystemObject)tmpList.get(j);
        com.dcivision.workflow.bean.WorkflowRecord wfRec = (com.dcivision.workflow.bean.WorkflowRecord)workflowRecordDAO.getObjectByTrackID(tmpObj.getTrackID());
        if (wfRec != null) {
          tmpRow.add(new Object[] {wfRec, tmpObj.getTrackID()});
        }
      }
    }
    request.setAttribute("workflowRelationshipList", listWorkflowRelation);
    mtmWfProgressSysObjDAO=null;
    workflowRecordDAO=null;
    // Retrive the workflow relationship.
    }
  
  public List searchDoc(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);

    ListDmsDocumentForm searchForm = (ListDmsDocumentForm) form;

    List docList = new ArrayList();

    try {
      String rootID = searchForm.getRootID();
      String parentID = searchForm.getParentID();
      String[] searchFolder = searchForm.getSearchFolder();
      List targetRootIDs = Utility.getList(searchFolder);
      String[] outerCriteriaValue = (String[]) request.getSession().
        getAttribute("outerCriteriaValue");
      searchForm.setOuterCriteriaValue(outerCriteriaValue);

      docList = docRetrievalManager.searchDocumentBySearchObject(searchForm, targetRootIDs);
      
      if (docList != null && docList.size() > 0) {
        DmsDocument tmpDoc = (DmsDocument) docList.get(0);
        String outerCriteria = tmpDoc.getOuterCriteria();
        searchForm.setOuterCriteria(outerCriteria);
        outerCriteriaValue = tmpDoc.getOuterCriteriaValue();
        request.getSession().setAttribute("outerCriteriaValue", outerCriteriaValue);
        searchForm.setOuterCriteriaValue(outerCriteriaValue);
      }
      
      if (DmsOperationConstant.SEARCH_RESULT_ALL.equals(searchForm.getSearchResultOpt())) {
        if (docList!=null) {
          // if equals SEARCH_RESULT_ALL, this method must be called by 'zip export' method. so we must filter unuseful records first.
          for (int i=(docList.size()-1); i>=0; i--) {
            DmsDocument dmsDocument = (DmsDocument)docList.get(i);
            if (!GlobalConstant.RECORD_STATUS_ACTIVE.equals(dmsDocument.getRecordStatus()) || DmsVersion.ARCHIVED_STATUS.equals(dmsDocument.getItemStatus())) {
              docList.remove(i);
            }else if (!DmsDocument.DOCUMENT_TYPE.equals(dmsDocument.getDocumentType()) && !DmsDocument.EMAIL_DOC_TYPE.equals(dmsDocument.getDocumentType()) && !DmsDocument.COMPOUND_DOC_TYPE.equals(dmsDocument.getDocumentType())) {
              docList.remove(i);
            }
          }
        }
      }

      //Use for List the target User Defined Fields Detail
      if (searchForm.getUserDefinedFieldID() != null) {
        List udfDetailList = docRetrievalManager.getUDFDetailList(TextUtility.parseIntegerObj(searchForm.getUserDefinedFieldID()));
        searchForm.setUdfDetailList(udfDetailList);
      }

      List docDetailList = searchForm.getDocumentDetails();
      if (docDetailList != null) {
        searchForm.setDocumentDetails(docDetailList);
      }
      sessionContainer = null;
      docRetrievalManager.release();
    } catch (ApplicationException appEx) {
      throw new ApplicationException(ErrorConstant.SYS_CHARACTER_ERROR, null, " \" ");
    } catch (Exception e) {
      log.error("Search error.", e);
      throw new ApplicationException(com.dcivision.dms.DmsErrorConstant.SEARCH_CRITERIA_NON_EXIST, e);
    } finally {
      conn = null;
    }
    return docList;
  }
  
  public List getDocList(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
  	//List docList = new ArrayList();
  	ListDmsDocumentForm docForm = (ListDmsDocumentForm)form;
  	//Connection conn = this.getConnection(request);
  	//SessionContainer sessionContainer = this.getSessionContainer(request);
  	//PermissionManager pm = sessionContainer.getPermissionManager();
  	
  	//DocumentRetrievalManager docRetrieval = new DocumentRetrievalManager(sessionContainer,conn);
  	//DmsDocumentDAObject documentDAO = new DmsDocumentDAObject(sessionContainer,conn);
  	//DmsRootDAObject dmsRootDAO = new DmsRootDAObject(sessionContainer,conn);
  	String opSearch = docForm.getAdvSearchOpt();
  	//List tmpDocList = documentDAO.getFullList(docForm);
  	List tmpDocList = null;

  	if (DmsOperationConstant.ATTR_SEARCH_OPERATION.equals(opSearch)) {
  		tmpDocList = searchDoc(mapping, docForm, request, response);
  	} else if (DmsOperationConstant.KEYWORD_SEARCH_OPERATION.equals(opSearch)) {
  		tmpDocList = searchKeywordDocument(mapping, docForm, request, response);
  	} else if (DmsOperationConstant.ATTR_REPLACE_OPERATION.equals(opSearch)) {
  		tmpDocList = replaceCriteria(mapping, docForm, request, response);
  	} else if (DmsOperationConstant.ATTR_BULK_SEARCH_OPERATION.equals(opSearch)) {
  		tmpDocList = bulkSearchDocument(mapping, docForm, request, response);
  	}
    /*
    if (tmpDocList != null){
     	for (int i=0;tmpDocList.size()>i;i++){
    		DmsDocument dmsDoc = (DmsDocument)tmpDocList.get(i);
    		
    		if (DmsDocument.DOCUMENT_LINK.equals(dmsDoc.getDocumentType())){    			
    			DmsDocument tmpDoc = docRetrieval.getRelationshipTargetDocument(dmsDoc.getID(),DmsDocument.DOCUMENT_LINK);
    			if (tmpDoc == null) continue;
    			DmsRoot dmsRoot = (DmsRoot)dmsRootDAO.getObjectByID(tmpDoc.getRootID());  
    			
      		if (pm.hasAccessRight(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT,tmpDoc.getID(),"R") || dmsRoot.getOwnerID().equals(this.getSessionContainer(request).getUserRecordID())){
      			docList.add(dmsDoc);
      		} 
    		} else {
    			DmsRoot dmsRoot = (DmsRoot)dmsRootDAO.getObjectByID(dmsDoc.getRootID());
      		if (pm.hasAccessRight(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT,dmsDoc.getID(),"R") || dmsRoot.getOwnerID().equals(this.getSessionContainer(request).getUserRecordID())){
      			docList.add(dmsDoc);
      		}
    		} 		      
    	}
    }
    */
  	return tmpDocList;
  }
  
  public List getPageList(ActionMapping mapping,AbstractSearchForm form, HttpServletRequest request,HttpServletResponse response) throws ApplicationException {
  	SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    PermissionManager pm = sessionContainer.getPermissionManager();
    DocumentRetrievalManager docRetrieval = new DocumentRetrievalManager(sessionContainer,conn);
    DmsRootDAObject dmsRootDAO = new DmsRootDAObject(sessionContainer,conn);
    
    ListDmsDocumentForm docForm = (ListDmsDocumentForm)form;
    
    
  	List result = new ArrayList();
  	int pageSize = TextUtility.parseInteger(docForm.getPageOffset());
    
    int recordCount = 0;
  	while (result.size() < pageSize) {
			List tmpList = this.getDocList(mapping,docForm,request,response);
      
      int offset = TextUtility.parseInteger(docForm.getCurStartRowNo()) + pageSize;
      
			for (int k = 0; (tmpList!=null && tmpList.size()>k); k++) {
        DmsDocument dmsDocument = (DmsDocument)tmpList.get(k);
        
        recordCount = dmsDocument.getRecordCount();
        
  			if (result.size() >= pageSize) {
          offset = dmsDocument.getRowNum();
          break; 
        }
  			
        if (DmsDocument.DOCUMENT_LINK.equals(dmsDocument.getDocumentType())) {
          DmsDocument tmpDoc = docRetrieval.getRelationshipTargetDocument(dmsDocument.getID(),DmsDocument.DOCUMENT_LINK);
          if (tmpDoc == null) {
            continue;
          }
          DmsRoot dmsRoot = (DmsRoot)dmsRootDAO.getObjectByID(tmpDoc.getRootID());  
          if (pm.hasAccessRight(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT,tmpDoc.getID(),"R") || dmsRoot.getOwnerID().equals(this.getSessionContainer(request).getUserRecordID())){
            result.add(dmsDocument);
          } 
        } else {
          DmsRoot dmsRoot = (DmsRoot)dmsRootDAO.getObjectByID(dmsDocument.getRootID());
          if (pm.hasAccessRight(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT,dmsDocument.getID(),"R") || dmsRoot.getOwnerID().equals(this.getSessionContainer(request).getUserRecordID())){
            result.add(dmsDocument);
          }
        }
  	  }
      
			//wiflish xie add for #EIP-3573.
			if(result.size() > 0) {
			  docForm.setCurStartRowNo(offset + "");
			}
			
      if (offset>recordCount) {
        break;
      }
		}
  	return result;
  }
  
  public String getCurPageCursor(String cursor,int CurPageNo) {
  	String curCursor = "1";
  	if (Utility.isEmpty(cursor)) {
      return curCursor;
    }
  	StringTokenizer cursorToken = new StringTokenizer(cursor,";");
  	
  	while (cursorToken.hasMoreTokens()){
  		String tmpCursor = cursorToken.nextToken();
  		if (tmpCursor.indexOf(CurPageNo + "-") != -1){
  			StringTokenizer tmpToken = new StringTokenizer(tmpCursor,"-");
  			tmpToken.nextToken();
  			curCursor  = tmpToken.nextToken();
  		}
  	}
  	return curCursor;
  }
  
  public List getAccessListData(AbstractSearchForm form,ActionMapping mapping, HttpServletRequest request,HttpServletResponse response) throws ApplicationException {
  	ListDmsDocumentForm docSearchForm = (ListDmsDocumentForm)form;
  	Integer pageAmountInc = SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.DMS_LIST_PAGEAMOUNT);
		int pageSize = TextUtility.parseInteger(docSearchForm.getPageOffset());
		int curPageNo = TextUtility.parseInteger(docSearchForm.getCurPageNO());
		int pageAmount = TextUtility.parseInteger(docSearchForm.getPageAmount());
    int lastPageNo = TextUtility.parseInteger(docSearchForm.getLastPageNO());
    
    //validate setting value
    pageAmountInc = pageAmountInc==null ? new Integer("5") : pageAmountInc;
    curPageNo = curPageNo<=0 ? curPageNo = 1: curPageNo;
		
    boolean needLoadDataFromDB = false;
    
		StringBuffer cursor = null;
    List result = null;
		if (docSearchForm.getCursor() != null && !docSearchForm.getCursor().equals("")) {
			cursor = new StringBuffer(docSearchForm.getCursor());
      docSearchForm.setCurStartRowNo(this.getCurPageCursor(cursor.toString(),curPageNo));
      
      result = this.getPageList(mapping,docSearchForm,request,response);
      
      if (curPageNo%pageAmountInc.intValue()==0 && curPageNo==pageAmount) {
        if (result.size()>=pageSize) {
          int recordCount = ((DmsDocument)result.get(0)).getRecordCount();
          int startRowNo = Integer.parseInt(docSearchForm.getCurStartRowNo());
          if (startRowNo<=recordCount) {
            needLoadDataFromDB = true;
          }
        }
      }
		} else {
			cursor = new StringBuffer();
      docSearchForm.setCurStartRowNo("1");
      pageAmount = 0;
      
      needLoadDataFromDB = true;
    }
    
    if (needLoadDataFromDB) {
      for (int loopTimes=0; loopTimes<pageAmountInc.intValue(); loopTimes++) {
        List cursorList = this.getPageList(mapping,docSearchForm,request,response);
        if (loopTimes==0 && (docSearchForm.getCursor() == null || docSearchForm.getCursor().equals(""))) {
          result = cursorList;
        }
        if (!Utility.isEmpty(cursorList)) {
          DmsDocument tmpFirstDocument = (DmsDocument)cursorList.get(0);
          cursor.append(++pageAmount);
          cursor.append("-");
          cursor.append(tmpFirstDocument.getRowNum());
          cursor.append(";");
          
          if (cursorList.size()<pageSize) {
            lastPageNo = -1;
            break;
          }
        } else {
          lastPageNo = -1;
          break;
        }
      }
		}
    
		docSearchForm.setCursor(cursor.toString());
		docSearchForm.setCurPageNO(curPageNo + "");
    docSearchForm.setPageAmount(pageAmount + "");
		docSearchForm.setLastPageNO(lastPageNo + "");
		request.setAttribute("curpageNo",curPageNo+"");
		request.setAttribute("pageAmount",pageAmount+"");
		request.setAttribute("lastPageNo",lastPageNo+"");
		request.setAttribute("cursor",cursor.toString());
		request.setAttribute("pageSize",pageSize+"");
		return result;
  }
  
  /*
   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   * 
   * Inner class section.
   * 
   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   */
  
  public class AdvanceSearchPageModel extends BasePageModel {

    private AdvanceSearchPageModel(ActionMapping mapping, ListDmsDocumentForm form, HttpServletRequest request, HttpServletResponse response) {
      super("", mapping, request, response);
      
      sessionContainer = SearchDmsDocumentAction.this.getSessionContainer(request);
      
      // Parse the page title key.
      parsePageTitleKey(form);
    }
    
    /*
     * Parse the page title key according to the search request.
     * TODO: Tidy up the search request attribute opMode and navMode using meaning words
     * in order to make action navigation and viwer dispatch simply and clearly.
     * <ul>
     *   <li>Advance Search --> common.label.advance_search</li>
     *   <li>Advance Search Result --> common.label.advance_search_result</li>
     *   <li>Keyword Search --> common.label.keyword_search</li>
     *   <li>Bulk Search --> common.label.bulk_search</li>
     * </ul>
     */
    private void parsePageTitleKey(ListDmsDocumentForm form) {
      String pageRequestSymbol = form.getSearchPage();
      String searchRequestSymbol = form.getAdvSearchOpt();
      
      if (Utility.isEmpty(pageRequestSymbol)) {
        setPageTitleKey("common.label.advance_search");
      } else if ("INDEX_SEARCH".equals(pageRequestSymbol)) {
        setPageTitleKey("common.label.advance_search");
      } else if ("BULK_SEARCH".equals(pageRequestSymbol)) {
        setPageTitleKey("common.label.bulk_search");   
      } else if ("KEY_WORD".equals(pageRequestSymbol)) {        
        setPageTitleKey("common.label.keyword_search");
      } else {        
        setPageTitleKey("common.label.advance_search");
      }
      
      if (!Utility.isEmpty(searchRequestSymbol) && "DMS.ATTR_KEYWORD_SEARCH".equals(searchRequestSymbol)) {        
        setPageTitleKey("common.label.keyword_search");
      }else if (!Utility.isEmpty(searchRequestSymbol) && "DMS.ATTR_BULK_SEARCH".equals(searchRequestSymbol)) {        
        setPageTitleKey("common.label.bulk_search");
      }
      
      // TODO: Redesign the PageTitleTag.
      // Block code underline is for adapting the logic of PageTitleTag.
      request.setAttribute(GlobalConstant.EXTEND_PAGE_TITLE, message(getPageTitleKey()));
      request.setAttribute(GlobalConstant.EXTEND_PAGE_TITLE_SHOW_ONLY, new Boolean(true));
    }
    
    private String message(String key) {
      
      if (key == null) {
        throw (new NullPointerException("The key of internationalization message must not null!"));
      }

      return (getResources(request).getMessage(sessionContainer.getSessionLocale(), key));
    }
  }
}